技术分享
首页
  • JavaScript

    • 构造函数和原型
    • Cookie和Session
    • Object.create(null)和{}
    • TypeScript配置
    • typescript入门到进阶
  • 框架

    • Vue-Router
    • React基础入门
  • 其它

    • Http协议
    • 跨域问题总结
  • 分析Promise实现
  • Axios源码分析
  • Webpack原理
  • vueRouter源码分析
  • Vue

    • Vite快速搭建Vue3+TypeScript项目
    • Cordova打包Vue项目的问题
    • Vue将汉字转为拼音,取出首字母
    • h5项目问题总结
  • JavaScript

    • new Function
  • 后端

    • Node.js中使用Crypto生成Token
    • Body-Parser处理多层对象的问题
  • 其它

    • 项目Demo汇总
    • Vuepress+Vercel搭建个人站点
    • 项目中能用到的
    • husky规范代码提交
  • Mongoose基础
  • Multer文件上传中间件的使用
  • JavaScript

    • 浅谈两数全等
    • JavaScript进制转换
    • 手写bind,apply,call和new
  • 算法

    • 数组去重和排序
    • 数组扁平化
    • 斐波那契数列
  • JavaScript 数据结构
  • 其它

    • webpack面试题
    • vite面试题
    • svg和canvas的优缺点
    • TypeScript面试题
    • Vue常见面试题
  • 计算机网络

    • 数据链路层
    • 网络层
  • Git的使用
  • Nginx的使用
  • CentOS7安装Nginx
  • 正则表达式
  • SEO搜索引擎优化
  • Serverless介绍
友链
GitHub (opens new window)

刘誉

总有人要赢,为什么不能是我
首页
  • JavaScript

    • 构造函数和原型
    • Cookie和Session
    • Object.create(null)和{}
    • TypeScript配置
    • typescript入门到进阶
  • 框架

    • Vue-Router
    • React基础入门
  • 其它

    • Http协议
    • 跨域问题总结
  • 分析Promise实现
  • Axios源码分析
  • Webpack原理
  • vueRouter源码分析
  • Vue

    • Vite快速搭建Vue3+TypeScript项目
    • Cordova打包Vue项目的问题
    • Vue将汉字转为拼音,取出首字母
    • h5项目问题总结
  • JavaScript

    • new Function
  • 后端

    • Node.js中使用Crypto生成Token
    • Body-Parser处理多层对象的问题
  • 其它

    • 项目Demo汇总
    • Vuepress+Vercel搭建个人站点
    • 项目中能用到的
    • husky规范代码提交
  • Mongoose基础
  • Multer文件上传中间件的使用
  • JavaScript

    • 浅谈两数全等
    • JavaScript进制转换
    • 手写bind,apply,call和new
  • 算法

    • 数组去重和排序
    • 数组扁平化
    • 斐波那契数列
  • JavaScript 数据结构
  • 其它

    • webpack面试题
    • vite面试题
    • svg和canvas的优缺点
    • TypeScript面试题
    • Vue常见面试题
  • 计算机网络

    • 数据链路层
    • 网络层
  • Git的使用
  • Nginx的使用
  • CentOS7安装Nginx
  • 正则表达式
  • SEO搜索引擎优化
  • Serverless介绍
友链
GitHub (opens new window)
  • js基础
  • vue入门
  • react基础入门
  • http协议
  • cookie和session
  • 跨域问题总结
  • 构造函数和原型
  • Object.create(null)和{}
  • TypeScript配置
  • Vue-Router
  • typescript入门到进阶
    • 安装
      • 快速创建一个 tsconfig.json 文件
      • 编写
    • 入门
      • 基础
      • 类型断言
      • 类型推断
      • 类型拓宽、类型缩小
    • 进阶
  • 前端
coderly
2021-08-08

typescript入门到进阶

# TypeScript入门到进阶

记录 TypeScript 学习经验

# 安装

npm install -g typescript

# 快速创建一个 tsconfig.json 文件

tsc --init

配置原文地址 (opens new window)

{
  "compilerOptions": {
    /* Basic Options */
    "target": "esnext", // target用于指定编译之后的版本目标 version:'es3'(default), 'es5', 'es2015', 'es2016', 'es2017', 'es2018', 'esnext'
    "module": "esnext", // 用来指定要使用的模块标准:'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'esnext'
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ], // lib 用于指定要包含在编译中的库文件,如果要使用一些es6 的新语法,你需要引入 es6 这个库,或者也可以写 es2015
    // "allowJs": true, // allowJs 设置的值为true或false,用来指定是否允许编译js文件,默认是false,即不编译js文件
    // "checkJs": true, // checkJs 的值为true或false,用来指定是否检查和报告js文件中的错误,默认是false
    "jsx": "preserve", // 指定jsx代码的开发环境:'preserve', 'react-native', 'react'
    // "declaration": true, // declaration 的值为 true或false,用来指定是否在编译的时候生成相应的 ".d.ts" 声明文件。如果为true,编译每个ts文件之后会生成一个js文件和一个声明文件。但是 declaration 和 allJs不能同时设定为true
    // "declarationMap": true, // 值为true或false,指定是否为声明文件 .d.ts 生成map文件
    "sourceMap": true, // sourceMap的值为true或false,用来指定编译时是否生成.map 文件
    // "outFile": "./", // outFile 用于指定将输出文件合并为一个文件,它的值为一个文件路径名,比如设置为 ./dist//main.js,则输出的文件为一个main.js,但是要注意,只有设置 module 的值为amd 和 system 模块时才支持这个配置
    // "outDir": "./", // outDir用来指定输出文件夹,值为一个文件夹路径字符串,输出的文件都将放置在这个文件夹
    // "rootDir": "./", // 用来指定编译文件的根目录,编译器会在根目录查找入口文件,如果编译器发现以 rootDir 的值作为根目录查找入口文件并不会把所有文件加载进去的话会报错,但是不会停止编译
    // "composite": true, // 是否编译构建引用项目
    // "removeComments": true, // removeComments值为true或false,用于指定是否将编译后的文件中的注释删掉,设为true的话即删掉注释,默认为false。
    // "noEmit": true, // 不生成编译文件,这个一般很少用了
    "importHelpers": true, // importHelpers的值为true或false,指定是否引入 tslib 里的辅助工具函数,默认为false
    // "downlevelIteration": true, // 当 target为 es5 或 es3 时,为 'for-of'、'spread' 和 'destructuring' 中的迭代器提供完全支持 
    // "isolatedModules": true, // isolatedModules 的值为true或false,指定是否将每个文件作为单独的模块,默认为true,它不可以和 declaration 同时设定
    /* Strict Type-Checking Options */
    "strict": true, // strict 的值为true或false,用于指定是否启动所有类型检查,如果设为true则会同时开启下面这几个严格类型检查,默认为false
    // "noImplicitAny": true, // noImplicitAny 的值为true或 false,如果我们没有为一些值设置明确的类型,编译器会默认认为这个值为any类型,如果设为 true,则如果没有设置明确的类型会报错,默认为false
    // "strictNullChecks": true, // strictNullChecks的值为true或false,当设为true时,null和undefined值不能赋值给非这两种类型的值,别的类型的值也不能赋给他们,除了any类型,还有个例外就是undefined可以赋值给void类型
    // "strictFunctionTypes": true, // strictFunctionTypes的值为true或false,用来指定是否使用函数参数双向协变检查
    // "strictBindCallApply": true, // strictBindCallApply的值为true或false,设为true后会对bind、call和apply绑定的方法的参数的检查是严格检测的
    // "strictPropertyInitialization": true, //strictPropertyInitialization的值为true或false,设为true后会检查类的非undefined属性是否已经在构造函数里初始化,如果要开启这项,需要同时开启strictNullChecks,默认为false
    // "noImplicitThis": true, // 当 this 表达式的值为 any 类型的时候,会生成一个错误
    // "alwaysStrict": true, // alwaysStrict的值为true或false,指定始终以严格模式检查每个模块,并且在编译之后的js文件中加入 'use strict' 字样,用来告诉浏览器该js为严格模式
    /* Additional Checks */
    // "noUnusedLocals": true, // noUnusedLocals的值为true或false,用于检查是否有定义了但是没有使用的变量,对于这一点的检测,使用eslint可以在你书写代码的时候做提示
    // "noUnusedParameters": true, // noUnusedParameters的值为true或false,用于检查是否有在函数体中没有使用的参数,这个也可以配合eslint来做检查,默认是false
    // "noImplicitReturns": true, // noImplicitReturns的值为true或false,用于检查函数是否有返回值,设为true后,如果函数没有返回值则会提示,默认是false
    // "noFallthroughCasesInSwitch": true, // noFallthroughCasesInSwitch的值为true或false,用于检查switch中是否有case没有使用break跳出switch,默认是false
    /* Module Resolution Options */
    "moduleResolution": "node", // moduleResolution用于选择模块解析策略,有 node 和 classic 两种类型,
    "baseUrl": ".", // baseUrl 用于设置解析非模块名称的基本目录,相对模块不会受 baseUrl 的影响
    "paths": {
      "@/*": [
        "src/*"
      ]
    }, // paths用于设置模块名到基于 baseUrl 的路径映射
    // "rootDirs": [
    //   "src/core"
    // ], // rootDirs 可以指定一个路径列表,在构建时编译器会将这个路径列表中的路径中的内容都放到一个文件夹中
    // "typeRoots": [], // typeRoots用来指定声明文件或文件夹的路径列表,如果指定了此项,则只有在这里列出的声明文件才会被加载
    "types": [
      "webpack-env"
    ], // types 用来指定需要包含的模块,只有在这里列出的模块的声明问渐渐才会被加载进来
    "allowSyntheticDefaultImports": true, // allowSyntheticDefaultImports的值为true或false,用来指定允许从没有默认导出的模块中默认导入
    "esModuleInterop": true, // 通过为导入内容创建命名空间,实现 commonjs 和 es 模块之间的互操作性
    // "preserveSymlinks": true, // 不把符号链接解析为其真实路径
    
    /* Source Map Options */
    // "sourceRoot": "", // sourceRoot 用于指定调试器应该找到 typescript 文件而不是源文件位置,这个值会被写进 .map文件里
    // "mapRoot": "", // mapRoot 用于指定调试器找到映射文件而非生成文件的位置,指定map文件的根路径,该选项会影响.map 文件中的source 属性
    // "inlineSourceMap": true, // inlineSourceMap的值为true或false,指定是否将map文件的内容和js文件编译在同一个js文件中,如果设为true,则map的内容会以 //# sourceMappingURL=然后接base64字符串的形式插入在js文件底部
    // "inlineSources": true, // inlineSources的值为true或false,用于指定是否进一步将 .ts文件的内容也包含到输出文件中
    /* Experimental Options */
    "experimentalDecorators": true, // experimentalDecorators的值为true或false,用于指定是否启用实验性的装饰器特性
    // "emitDecoratorMetadata": false // emitDecoratorMetadata的值为true或false,用于指定是否为装饰器提供元数据支持
  },
  // "files": [], // files可以配置一个数组列表,里面包含指定文件的相对或绝对路径,编译器在编译的时候只会编译包含在files 中列出的文件。如果不指定,则取决于有没有include选项,如果没有include选项,则默认会编译根目录以及所有子目录中的文件
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ], // include 也可以指定要编译的路径列表,但是和 files 的区别在于,这里的路径可以是文件夹,也可以是文件,可以使用相对路径和绝对路径,而且可以使用通配符,
  "exclude": [
    "node_modules"
  ], // exclude 表示要排除的、不编译的文件、它也可以指定一个列表,规则和 include 一样,可以是文件也可以是文件夹,可以是相对路径或绝对路径,可以使用通配符
  // "extends": "", // extends 可以通过指定一个其它的 tsconfig.json文件路径,来继承这个配置文件里的配置,继承来的文件的配置会覆盖当前文件定义的配置。ts在3.2版本开始,支持继承一个来自node.js包的tsconfig.json配置文件
  // "compileOnSave": true, // compileOnSave的值是true或 false,如果为true,在我们编辑了项目中文件保存的时候,编译器会根据 tsconfig.json 的配置重新生成文件,不过这个要编辑器支持
  // "references": [] // 一个对象数组,指定要引用的项目
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

# 编写

  • add.ts
function add (num1: number, num2: number) {
  return num1 + num2
}
console.log(add(1, 3))
1
2
3
4
  1. 使用 tsc(TypeScript Compiler)命令将 .ts 文件转译为 .js 文件,执行命令
    tsc add.ts

  2. 使用 ts-node 运行 ts 代码,本质上直接运行ts(而非运行编译后的js)

    • npm install ts-node -g
    • ts-node add.ts

# 入门

静态类型检测:在编译时期,静态类型的编程语言即可准确地发现类型错误
TypeScript 编译器将通过对比检测变量接收值得类型与我们显示注解得类型从而检测类型是否存在错误

# 基础

# 原始类型

  • string
  • number
  • boolean
  • null
  • undefined
  • symbol
  • bigint

# 复杂类型

  • 数组
  • 元组:可以限制数组元素的个数和类型,它特别适合用来实现多值返回
    import { useState } from 'react'
    function useCount() {
      const [count, setCount] = useState(0)
      return ....
    }
    
    1
    2
    3
    4
    5

# 特殊类型

  • any:指的是一个任意类型,它是官方提供的一个选择性绕过静态类型检测的作弊方式

    • 可以把任何类型的值赋值给 any 类型的变量
    • 可以把 any 类型的值赋值给任意类型(除 never 以外)的变量
    • any 类型会在对象的调用链中进行传导,即所有 any 类型的任意属性的类型都是 any
  • unknown:用来描述类型并不确定的变量

    • 可以将任意类型的值赋值给 unknown
    • unknown 类型的值只能赋值给 unknown 或 any
  • void,undefined,null:实际上并没有太大的用处

    • void 仅适用于表示没有返回值的函数,即该函数没有返回值
    • undefined 的表示一个可缺省、未定义的属性,主要体现在接口类型上
    • null 表明对象或属性可能是空值,主要体现在接口制定上
  • never:表示永远不会发生值的类型

    • never 是所有类型的子类型
    • 可以给所有类型赋值
    • 除了 never 自身以外,其他类型(包括 any 在内的类型)都不能为 never 类型赋值
  • object:表示非原始类型的类型

    • 非 string、number、boolean、null、undefined、symbol、bigint

# 字面量类型

  • 字符串字面量类型

    • 字符串字面量联合类型:type direction = 'up' | 'down'
  • 数字字面量类型

  • 布尔字面量类型

let age: 18 = 18
let sex: true = true
let name: 'this is my name' = 'this is my name'

// 联合类型
interface Person {
  sex: true | false;
  age: 18 | 19 | 20;
  name: 'au' | 'coderly';
}
1
2
3
4
5
6
7
8
9
10

# 函数类型

通过 function 字面量和箭头函数的形式定义函数
可以显式指定函数参数和返回值的类型

# 可缺省和可推断的返回值类型

函数返回值的类型可以在 TypeScript 中被推断出来,即可缺省

# 参数类型
  • 可选参数和默认参数
// ? 代表该参数可以缺省
function log(message?: string) {
  return message
}

// = 后面的是默认参数
function add(num1 = 1, num2 = 2) {
  return num1 + num2
}
1
2
3
4
5
6
7
8
9
# 剩余参数
function add(...nums: number[]) {
    return nums.reduce((a, b) => a + b, 0)
}
1
2
3

剩余参数应该作为函数的最后一个参数,例如下面的是错误的

// 剩余参数 只能作为最后一个参数 
function add(...nums: number[], num1) { // ❌
    return nums.reduce((a, b) => a + b, 0) + num1
}

// 正确写法
function add(num1, ...nums: number[]) { // ✔
    return nums.reduce((a, b) => a + b, 0) + num1
}
1
2
3
4
5
6
7
8
9
# this
  • typescript 中使用 this 必须显式声明 this 的类型
  • 不显式声明 this 的类型,将是 any 类型

# 类型断言

可以用来手动指定一个值的类型
父子,子父类型之间可以使用类型断言进行转换

let age = 18

console.log((age as any).length) // number 类型没有 length 属性,断言 any 类型可以通过类型检测
1
2
3

# 类型推断

  • 如果没有明确的指定类型,那么 TypeScript 会依照类型推论(Type Inference)的规则推断出一个类型
let age = 18 // 被推断为 number 类型

age = 'au' // 因为推断为 number 类型,给它赋值 string 类型将会报错
1
2
3
  • 如果定义的时候没有赋值,不管之后有没有赋值,都会被推断成 any 类型而完全不被类型检查
let age // 定义的时候没有赋值,被推断为 any 类型

age = '18'
1
2
3

# 类型拓宽、类型缩小

# 进阶

#TypeScript
上次更新: 2021/08/09, 19:24:51
Vue-Router

← Vue-Router

最近更新
01
代码片段
04-22
02
koa全家桶
03-29
03
mocks项目复盘
03-29
更多文章>
Theme by Vdoing | Copyright © 2021-2022 coderly | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式