TypeScript常用类型速查手册
TypeScript常用类型速查手册
JavaScript
是一个天生的弱类型语言,即变量申明的时候不需要指定类型,不同类型的变量之间也可以相互赋值。如果你已经习惯了这种写法,用起来也是挺爽的,因为不需要特意关心变量类型,直接写就行。但是这样做也很容易导致BUG,而且这些BUG基本都是运行时才出现,因为没有类型,静态检查是查不出问题的,只有运行时报错,可能直接一来就是个线上BUG。
TypeScript
就是为JavaScript
加上了类型检查,可以用静态检查排查出类型相关的问题,从而避免了线上的BUG。现在TypeScript
已经很流行了,我们的新项目也引入了他,但是我用的不是很熟练,经常遇到不知道怎么定义类型的问题。所以我整理了这一份速查手册,从基本类型到interface
,泛型这些都有,分享给大家~
基本类型
JavaScript
的数据类型主要分为值类型和引用类型两大类。
值类型有string
, number
, boolean
, undefined
, 另外ES6引入了symbol
, ES2020引入了bigint
。这些类型都可以直接作为TS类型使用:
1 | let a: string = 'hello'; |
另外一大类是引用类型,主要是object
和function
,当然你可以将他们直接作为TS类型使用,但是我们不推荐这么做,object
最好使用接口或者类来定义,而function
最好给出详细的参数定义。我们先来个最简单的写法,后面单独看详细的推荐做法:
1 | let a: object = {}; |
一个变量可能有多个值的话,可以使用联合类型定义:
1 | let a: string | number | null = 123; |
上面这样申明一个变量是最常见的:
1 | let/const 名称: 类型 = 初始值; |
但是如果你有了初始值也可以不写类型,比如:
1 | let a = 'str'; // TS自动推导a是string类型 |
数组
长度不确定的数组
可以使用
T[]
这种形式:1
let a: number[] = [1, 2, 3];
也可以使用
Array<T>
这种形式:1
let a: Array<number> = [1, 2, 3];
长度确定的数组或者元素类型不一样的数组
可以使用元组[string, number]
这种形式:
1 | let a: [string, number] = ['hello', 123]; |
不确定的类型
有时候我们确实会遇到类型不确定的情况,这时候我们可能会用到any
,never
,void
, unknown
。他们的主要作用和区别是:
any
:放弃TS的类型检查和保护,可以是任意值,跟普通JS一样,一般不推荐使用这个:1
2
3let a: any = ['hello', 123];
a = 'hello';
a = 123;never
:申明函数返回值,表示这个函数永远不会返回,一般用不到。因为一个函数你即使不写return
也会默认返回undefined
,永远不返回的是指无限循环之类,或者肯定抛出错误的:1
2
3
4
5
6
7let a: () => never = () => {
throw new Error();
}
let b: () => never = () => {
while (true) {}
}void
: 表示函数没有返回值,其实就是默认返回undefined
:1
2
3
4
5
6
7
8
9
10
11let a: () => void = () => {
let b = 1;
console.log(b);
}
let c: () => void = () => {
let b = 1;
console.log(b);
return undefined;
}unknown
:安全的未知类型,在可以使用any
的地方,推荐换成unknown
,会有类型保护。具体来说就是unknown
只能被赋值,而不能赋值给别人,而且不能直接使用,要想使用必须自己先做动态类型检测。比如下面这样直接用会报错:
1
2
3let a: (b: unknown) => void = (b) => {
let c:number = b + 1; // 报错:Object is of type 'unknown'.ts(2571)
}但是如果你使用前先检测一下就没问题:
1
2
3
4
5let a: (b: unknown) => void = (b) => {
if(typeof b === 'number') {
let c:number = b + 1;
}
}所以
unknown
说直白点就是逼你在使用前先检测类型,自己保障类型安全。
函数
一般函数的定义是这样的:
1 | function intro(name: string, age: number): string { |
相较于普通的JS函数来说,只是给参数和返回值规定了类型而已。
函数是可以赋值给变量的,这个变量的类型应该是被赋值函数的签名,比如将上面的函数赋值给一个变量:
1 | const introFun: (name: string, age: number) => string = intro; |
这里的introFun
的签名就是
1 | (name: string, age: number) => string |
这也是一个函数签名的标准格式:
1 | (参数1: 参数1类型, 参数2: 参数2类型 ...) => 返回值类型 |
这种函数变量我们也经常作为参数传递,比如另一个函数接收introFun
作为参数,那可能就是这样的:
1 | function wrapper(place: string, introFun: (name: string, age: number) => string): string { |
这里的introFun
的函数签名太长了,我们可以用type
给他定义个别名:
1 | type TIntroFun = (name: string, age: number) => string; |
然后就可以用TIntroFun
替换那个长长的签名了:
1 | function wrapper(place: string, introFun: TIntroFun): string { |
可选参数
上面那样写的函数参数都是必须要传的,不传就报错,但是有时候我们有些参数是可选的,可选参数需要在参数名字后面加?
:
1 | function intro(name: string, age?: number): string { |
像age?: number
这种可选参数,TS其实是自动联合了undefined
类型,等价于age: string | undefined
。
参数默认值
函数的参数是可以给默认值的,比如上面的name
可以给一个默认值小飞
:
1 | function intro(name: string = '小飞', age?: number): string { |
根据我们前面变量那里说的,一个变量有了初始值,其类型TS是可以自动推导的,所以name
的类型可以省略,变成这样:
1 | function intro(name = '小飞', age?: number): string { |
但是可选参数不能给默认值,给了就会报错。
参数不确定
JS函数非常灵活,一个函数是可以支持不确定个数的参数的,比如这个加法函数:
1 | function add(...args) { |
这个函数接收任意多个数字,返回他们的和,这种函数类型怎么定义呢?args
其实是一个数组,按照数组类型给他就行了:
1 | function add(...args: number[]): number { |
那如果参数的前面几个是确定的,剩余参数不确定怎么写呢?结合我们前面的函数参数类型和...args
就行了:
1 | function add(name: string, ...args: number[]): string { |