掌握 TS 这些工具类型,让你开发事半功倍
本文于475天之前发表,文中内容可能已经过时。
创建了一个 “重学TypeScript” 的微信群,想加群的小伙伴,加我微信 “semlinker”,备注 “1” 。阿里、京东、腾讯的大佬都在群里等你哟。
一、类型别名
TypeScript 提供了为类型注解设置别名的便捷语法,你可以使用 type SomeName = someValidTypeAnnotation
来创建别名,比如:
1 | type Pet = 'cat' | 'dog'; |
二、基础知识
为了让大家能更好地理解并掌握 TypeScript 内置类型别名,我们先来介绍一下相关的一些基础知识。
2.1 typeof
在 TypeScript 中,typeof
操作符可以用来获取一个变量声明或对象的类型。
1 | interface Person { |
2.2 keyof
keyof
操作符可以用来一个对象中的所有 key 值:
1 | interface Person { |
2.3 in
in
用来遍历枚举类型:
1 | type Keys = "a" | "b" | "c" |
2.4 infer
在条件类型语句中,可以用 infer
声明一个类型变量并且对它进行使用。
1 | type ReturnType<T> = T extends ( |
以上代码中 infer R
就是声明一个变量来承载传入函数签名的返回值类型,简单说就是用它取到函数返回值的类型方便之后使用。
2.5 extends
有时候我们定义的泛型不想过于灵活或者说想继承某些类等,可以通过 extends 关键字添加泛型约束。
1 | interface ILengthwise { |
现在这个泛型函数被定义了约束,因此它不再是适用于任意类型:
1 | loggingIdentity(3); // Error, number doesn't have a .length property |
这时我们需要传入符合约束类型的值,必须包含必须的属性:
1 | loggingIdentity({length: 10, value: 3}); |
三、内置类型别名
3.1 Partial
Partial<T>
的作用就是将某个类型里的属性全部变为可选项 ?
。
定义:
1 | // node_modules/typescript/lib/lib.es5.d.ts |
在以上代码中,首先通过 keyof T
拿到 T
的所有属性名,然后使用 in
进行遍历,将值赋给 P
,最后通过 T[P]
取得相应的属性值。中间的 ?
,用于将所有属性变为可选。
示例:
1 | interface Todo { |
3.2 Required
Required<T>
的作用就是将某个类型里的属性全部变为必选项。
定义:
1 | // node_modules/typescript/lib/lib.es5.d.ts |
以上代码中,-?
的作用就是移除可选项 ?
。
示例:
1 | interface Props { |
3.3 Readonly
Readonly<T>
的作用是将某个类型所有属性变为只读属性,也就意味着这些属性不能被重新赋值。
定义:
1 | // node_modules/typescript/lib/lib.es5.d.ts |
如果将上面的 readonly
改成 -readonly
, 就是移除子属性的 readonly
标识。
示例:
1 | interface Todo { |
Readonly<T>
对于表示在运行时将赋值失败的表达式很有用(比如,当尝试重新赋值冻结对象的属性时)。
1 | function freeze<T>(obj: T): Readonly<T>; |
3.4 Record
Record<K extends keyof any, T>
的作用是将 K
中所有的属性的值转化为 T
类型。
定义:
1 | // node_modules/typescript/lib/lib.es5.d.ts |
示例:
1 | interface PageInfo { |
3.5 Pick
Pick<T, K extends keyof T>
的作用是将某个类型中的子属性挑出来,变成包含这个类型部分属性的子类型。
定义:
1 | // node_modules/typescript/lib/lib.es5.d.ts |
示例:
1 | interface Todo { |
3.6 Exclude
Exclude<T, U>
的作用是将某个类型中属于另一个的类型移除掉。
定义:
1 | // node_modules/typescript/lib/lib.es5.d.ts |
如果 T
能赋值给 U
类型的话,那么就会返回 never
类型,否则返回 T
类型。最终实现的效果就是将 T
中某些属于 U
的类型移除掉。
示例:
1 | type T0 = Exclude<"a" | "b" | "c", "a">; // "b" | "c" |
3.7 Extract
Extract<T, U>
的作用是从 T
中提取出 U
。
定义:
1 | // node_modules/typescript/lib/lib.es5.d.ts |
如果 T
能赋值给 U
类型的话,那么就会返回 T
类型,否则返回 never
类型。
示例:
1 | type T0 = Extract<"a" | "b" | "c", "a" | "f">; // "a" |
3.8 Omit
Omit<T, K extends keyof any>
的作用是使用 T
类型中除了 K
类型的所有属性,来构造一个新的类型。
定义:
1 | // node_modules/typescript/lib/lib.es5.d.ts |
示例:
1 | interface Todo { |
3.9 NonNullable
NonNullable<T>
的作用是用来过滤类型中的 null
及 undefined
类型。
定义:
1 | // node_modules/typescript/lib/lib.es5.d.ts |
示例:
1 | type T0 = NonNullable<string | number | undefined>; // string | number |
3.10 ReturnType
ReturnType<T>
的作用是用于获取函数 T
的返回类型。
定义:
1 | // node_modules/typescript/lib/lib.es5.d.ts |
示例:
1 | type T0 = ReturnType<() => string>; // string |
3.11 InstanceType
InstanceType
的作用是获取构造函数类型的实例类型。
定义:
1 | // node_modules/typescript/lib/lib.es5.d.ts |
示例:
1 | class C { |
3.12 ThisType
ThisType<T>
的作用是用于指定上下文对象的类型。
定义:
1 | // node_modules/typescript/lib/lib.es5.d.ts |
注意:使用
ThisType<T>
时,必须确保--noImplicitThis
标志设置为 true。
示例:
1 | interface Person { |
3.13 Parameters
Parameters<T>
的作用是用于获得函数的参数类型组成的元组类型。
定义:
1 | // node_modules/typescript/lib/lib.es5.d.ts |
示例:
1 | type A = Parameters<() => void>; // [] |
3.14 ConstructorParameters
ConstructorParameters<T>
的作用是提取构造函数类型的所有参数类型。它会生成具有所有参数类型的元组类型(如果 T 不是函数,则返回的是 never 类型)。
定义:
1 | // node_modules/typescript/lib/lib.es5.d.ts |
示例:
1 | type A = ConstructorParameters<ErrorConstructor>; // [(string | undefined)?] |
四、参考资源
欢迎小伙伴们订阅全栈修仙之路,及时阅读 TypeScript、Node/Deno、Angular 技术栈最新文章。
