摘要:官方文档高级类型优先阅读,建议阅读英文文档。关键字这个关键字是在版本引入的在条件类型语句中,该关键字用于替代手动获取类型。源码解释使用条件判断完成示例官方作用该类型可以获得函数的参数类型组成的元组类型。
学习 TypeScript 到一定阶段,必须要学会高阶类型的使用,否则一些复杂的场景若是用 any 类型来处理的话,也就失去了 TS 类型检查的意义。
本文罗列了 TypeScript 常用的高阶类型,包含 官方 、以及 常用的非官方 的高级类型声明,该手册直接硬啃的话有些枯燥,适合平时快速查阅,使用 Ctrl+F 来查找关键词来定位即可。
官方文档 - 高级类型:优先阅读,建议阅读英文文档。附 中文文档,有人做了专门的读书笔记 Typescript学习记录:高级类型
TypeScript: Built-in generic types:推荐,用案例详细解释高阶类型的使用;
TS 一些工具泛型的使用及其实现:TS 内置工具泛型高阶使用
TypeScript 2.1 新特性一览:查找/映射类型及 any 类型的推断 都是在 2.1 版本引入的
TypeScript 2.8:Exclude 等条件类型是在 2.8 版本引入的,附中文 TypeScript 2.8 引入条件类型
lib.es2015.d.ts:大部分的声明在这个文件中可以找到
TypeScript 强大的类型别名:行文结构比较合理,也比较完善,可以当手册来查
1、基础 1.1、交叉类型交叉类型是将 多个类型合并为一个类型。 这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性。
Person & Serializable & Loggable
同时是 Person 和 Serializable 和 Loggable。
就是说这个类型的对象同时拥有了这三种类型的成员
示例:extend 融合方法
function extend(first: T, second: U): T & U { let result = {}; for (let id in first) { ( result)[id] = ( first)[id]; } for (let id in second) { if (!result.hasOwnProperty(id)) { ( result)[id] = ( second)[id]; } } return result; }
特殊情况:
T | never = T
T & never = never (which #16446 provides)
T extends U ? X : Y
表示,如果 T 可以赋值给 U (类型兼容),则返回 X,否则返回 Y;
1.3、使用 keyof 和 inkeyof 可以用来取得一个对象接口的所有 key 值:
interface Foo { name: string; age: number } type T = keyof Foo // -> "name" | "age"
而 in 则可以遍历枚举类型, 例如:
type Keys = "a" | "b" type Obj = { [p in Keys]: any } // -> { a: any, b: any }
keyof 产生联合类型, in 则可以遍历枚举类型, 所以他们经常一起使用。
1.4、infer 关键字infer 这个关键字是在 TS 2.8 版本引入的, 在条件类型语句中,该关键字用于替代手动获取类型。
TypeScript 为此提供了一个示例,他们创建了一个叫作 Flatten 的类型,用于将数组转成他们需要的元素类型:
type Flatten= T extends any[] ? T[number] : T;
如果使用关键字 infer 就可以将上面的代码简化成:
type Flatten2、映射类型 2.1、Partial(官方)= T extends Array ? U : T;
作用:将传入的属性变为可选项
源码:
type Partial= { [P in keyof T]?: T[P] };
解释:
keyof T 拿到 T 所有属性名
然后 in 进行遍历, 将值赋给 P, 最后 T[P] 取得相应属性的值.
结合中间的 ? 我们就明白了 Partial 的含义了.
扩展:内置的 Partial 有个局限性,就是只支持处理第一层的属性,如果是嵌套多层的就没有效果了,不过可以如下自定义:
type PowerPartial2.2、Required(官方)= { // 如果是 object,则递归类型 [U in keyof T]?: T[U] extends object ? PowerPartial : T[U] };
作用:将传入的属性变为必选项
源码:
type Required= { [P in keyof T]-?: T[P] };
解释:
我们发现一个有意思的用法 -?, 这里很好理解就是将可选项代表的 ? 去掉, 从而让这个类型变成必选项
与之对应的还有个 +? , 这个含义自然与 -? 之前相反, 它是用来把属性变成可选项的
2.3、Readonly(官方)作用:将传入的属性变为只读选项
源码:
type Readonly= { readonly [P in keyof T]: T[P] };
扩展:在 巧用 Typescript 中,作者创建了 DeepReadonly 的声明,使用 递归 的思想让任何子属性都不可更改
type DeepReadonly2.4、Mutable(第三方)= { readonly [P in keyof T]: DeepReadonly ; } const a = { foo: { bar: 22 } } const b = a as DeepReadonly b.foo.bar = 33 // Hey, stop!
作用:将 T 的所有属性的 readonly 移除
源码:
type Mutable= { -readonly [P in keyof T]: T[P] }
解释:
这一对加减符号操作符 + 和 -, 进行的不是变量的之间的进行加减而是对 readonly 属性进行加减
2.5、Record(官方)作用:将 K 中所有的属性的值转化为 T 类型
源码:
type Record= { [P in K]: T };
示例:
// 对所有 T 类型的属性 K, 将它转换为 U function mapObject2.6、Pick(官方)(obj: Record , f: (x: T) => U): Record ; const names = { foo: "hello", bar: "world", baz: "bye" }; const lengths = mapObject(names, s => s.length); // { foo: number, bar: number, baz: number }
作用:从 T 中取出 一系列 K 的属性
源码:
type Pick= { [P in K]: T[P] };
示例:
// 从 T 挑选一些属性 K declare function pick3、条件类型 3.1、Exclude(官方)(obj: T, ...keys: K[]): Pick ; const nameAndAgeOnly = pick(person, "name", "age"); // { name: string, age: number }
某些地方也称为 Diff
作用:从 T 中剔除可以赋值给 U 的类型,换言之就是从T 中排除 U
源码:
type Exclude= T extends U ? never : T;
解释:
在 ts 2.8 中引入了一个条件类型, T extends U ? X : Y 表示如果 T 是 U 的子类型的话,那么就会返回 X,否则返回 Y
对于联合类型来说会自动分发条件,例如 T extends U ? X : Y, T 可能是 A | B 的联合类型, 那实际情况就变成(A extends U ? X : Y) | (B extends U ? X : Y)
示例:
type T = Exclude<1 | 2, 1 | 3> // -> 2
参考文档:
Add support for literal type subtraction
TypeScript在React高阶组件中的使用技巧
3.2、Extract(官方)作用:从 T 中提取出包含在 U 的类型,换言之就是从T 中提取出 U 子集
源码:
type Extract= T extends U ? T : never;
示例:
type T = Extract<1 | 2, 1 | 3> // -> 13.3、Omit (第三方)
作用:从 T 中忽略在 K 中的属性名 ,实现忽略对象某些属性功能,多在高阶组件中使用
源码:
type Omit= Pick >
示例:
type Foo = Omit<{name: string, age: number}, "name"> // -> { age: number }3.4、Overwrite(第三方)
作用: T 中的定义被在 K 中的内容所覆盖,多在高阶组件中使用,内部借助 Diff 操作实现
源码:
type Overwrite= { [P in Exclude ]: T[P] } & U;
示例:
type Item1 = { a: string, b: number, c: boolean }; type Item2 = { a: number }; type T3 = Overwrite3.5、ReturnType (官方)// { a: number, b: number, c: boolean };
作用:从 T 中忽略在 K 中的属性名 ,实现忽略对象某些属性功能,多在高阶组件中使用
源码:
type ReturnType= T extends ( ...args: any[] ) => infer R ? R : any;
解释:
我们可以用 infer 声明一个类型变量,是用它获取函数的返回类型,简单说就是用它取到函数返回值的类型方便之后使用.
示例:
function foo(x: number): Array4、函数相关 4.1、ThisType(官方){ return [x]; } type fn = ReturnType ;
作用:用于指定上下文对象类型的
源码:
// node_modules/typescript/lib/lib.es5.d.ts interface ThisType{ }
解释:
可以看到声明中只有一个接口,没有任何的实现
说明这个类型是在 TS 源码层面支持的,而不是通过类型变换。
示例:
interface Person { name: string; age: number; } const obj: ThisType= { dosth() { this.name // string } }
这样的话,就可以指定 obj 里的所有方法里的上下文对象改成 Person 这个类型了
4.2、InstanceType(官方)作用:用于获取构造函数类型的实例类型
源码:
// node_modules/typescript/lib/lib.es5.d.ts type InstanceTypeany> = T extends new (...args: any[]) => infer R ? R : any;
解释:
使用 infer 和 extends 条件判断完成
示例:
class C { x = 0; y = 0; } type T20 = InstanceType; // C type T21 = InstanceType ; // any type T22 = InstanceType ; // any type T23 = InstanceType ; // Error type T24 = InstanceType ; // Error
这样的话,就可以指定 obj 里的所有方法里的上下文对象改成 Person 这个类型了
4.3、NonNullable(官方)作用:这个类型可以用来过滤类型中的 null 及 undefined 类型。
源码:
// node_modules/typescript/lib/lib.es5.d.ts type NonNullable= T extends null | undefined ? never : T;
解释:
使用 extends 条件判断完成
示例:
type T22 = string | number | null; type T23 = NonNullable4.4、Parameters(官方); // -> string | number;
作用:该类型可以获得函数的参数类型组成的元组类型。
源码:
// node_modules/typescript/lib/lib.es5.d.ts type Parametersany> = T extends (...args: infer P) => any ? P : never;
解释:
使用 infer 和 extends 条件判断完成
示例:
function foo(x: number): Array{ return [x]; } type P = Parameters ; // -> [number]
此时 P 的真实类型就是 foo 的参数组成的元组类型 [number]
4.5、ConstructorParameters(官方)作用:获得类的参数类型组成的元组类型。
源码:
// node_modules/typescript/lib/lib.es5.d.ts type ConstructorParametersany> = T extends new (...args: infer P) => any ? P : never;
解释:
使用 infer 和 extends 条件判断完成
示例:
class Person { private firstName: string; private lastName: string; constructor(firstName: string, lastName: string) { this.firstName = firstName; this.lastName = lastName; } } type P = ConstructorParameters; // -> [string, string]
此时 P 就是 Person 中 constructor 的参数 firstName 和 lastName 的类型所组成的元组类型 [string, string]。
下面的是我的公众号二维码图片,欢迎关注。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/109289.html
摘要:阿里蒋航将使前后端从分离再度走向融合阅读原文掀起新的前端技术变革阅读原文速查手册高级类型阅读原文工程化从头搭建一个项目阅读原文文件聊聊中的字段周边深入理解浏览器原理阅读原文 Serverless 1. 阿里蒋航:Serverless 将使前后端从分离再度走向融合 阅读原文 2. Serverless 掀起新的前端技术变革 阅读原文 TypeScript 1. 【速查手册】TypeScr...
摘要:一些知识点有哪些方法方法前端从入门菜鸟到实践老司机所需要的资料与指南合集前端掘金前端从入门菜鸟到实践老司机所需要的资料与指南合集归属于笔者的前端入门与最佳实践。 工欲善其事必先利其器-前端实习简历篇 - 掘金 有幸认识很多在大厂工作的学长,在春招正式开始前为我提供很多内部推荐的机会,非常感谢他们对我的帮助。现在就要去北京了,对第一份正式的实习工作也充满期待,也希望把自己遇到的一些问题和...
摘要:笔者整理了中内置方法的速查表,包含内置方法列表处理方法字典处理方法元组处理方法集合处理方法序列类型的切片方法共计多个方法,点击图片查看原图下载。 笔者整理了Python3中内置方法的速查表,包含: 内置方法 列表处理方法 字典处理方法 元组处理方法 集合处理方法 序列类型的切片方法 共计100多个方法,点击图片——查看原图——下载。 showImg(https://sfault-i...
showImg(http://ww2.sinaimg.cn/large/005SFY0kjw1f2mt468a0cj31bs10mtk8.jpg); GitHub 项目在此: https://github.com/Aufree/laravel5-cheat... 本项目由 @Aufree 和 @Summer 整理维护。 说明 最近在开始使用 Laravel 进行开发, 在学习过程中无意间发现了 L...
摘要:编程书籍的整理和收集最近一直在学习深度学习和机器学习的东西,发现深入地去学习就需要不断的去提高自己算法和高数的能力然后也找了很多的书和文章,随着不断的学习,也整理了下自己的学习笔记准备分享出来给大家后续的文章和总结会继续分享,先分享一部分的 编程书籍的整理和收集 最近一直在学习deep learning深度学习和机器学习的东西,发现深入地去学习就需要不断的去提高自己算法和高数的能力然后...
阅读 2384·2023-04-26 02:54
阅读 2306·2021-10-14 09:43
阅读 3340·2021-09-22 15:19
阅读 2836·2019-08-30 15:44
阅读 2696·2019-08-30 12:54
阅读 979·2019-08-29 18:43
阅读 1931·2019-08-29 17:12
阅读 1324·2019-08-29 16:40