翼度科技»论坛 编程开发 JavaScript 查看内容

TypeScript条件类型示例全面讲解

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
Typescript 高阶类型


索引类型

keyof 会提取interface中的key
  1. class KeyCls {
  2. name: string
  3. age: number
  4. }
  5. type KeyClsExample1 = keyof KeyCls // name | age
  6. function getParams(params: keyof KeyCls) {}
  7. getParams('name') // 正常
  8. getParams('age') // 正常
  9. getParams('sex') // 报错
复制代码
in 可以遍历枚举类型
  1. type Keys = 'a' | 'b'
  2. type Obj = {
  3. [p in Keys]: any;
  4. }
  5. // type Obj = {
  6. //     a: any;
  7. //     b: any;
  8. // }
复制代码
extends
  1. type TExtends<T, U> = T extends U ? number : never;
  2. type TExtendExample = TExtends<number, number | string> // number
  3. // 联合类型, 表示如果T中的类型是U的子集, 那么返回never, 否则返回T, 这个过程可以理解为对T中的类型进行一次遍历, 每个类型都执行一次extends
  4. type NonNullable1<T, U> = T extends U ? never : T
  5. type NonExample = NonNullable1<null | string, null | undefined> // string
复制代码
Pick 英文意思挑选, 也就是从某种类型中挑选出一个或多个属性
  1. interface Todo {
  2. title: string
  3. desc: string
  4. Done: boolean
  5. }
  6. type TodoPreview = Pick<Todo, 'Done'>
  7. // type TodoPreview = {
  8. //     Done: boolean;
  9. // }
  10. // 实现
  11. type MyPick<T, K extends keyof T = keyof T> = {
  12. [P in K]: T[P]
  13. }
  14. // K in extends keyof T = keyof T, 意思是取值必须是在T的key上面取, 如果不传递取值默认为keyof T,所有的key, 内部取值是如果传递了K, 则属性就在K中任意一个
复制代码
Readonly 只读
  1. interface Todo {
  2. title: string
  3. desc: string
  4. Done: boolean
  5. }
  6. const todo: Pick<Readonly<Todo>, 'title'> = {
  7. title: '你好'
  8. }
  9. todo.title = '啊啊啊'; // 无法为“title”赋值,因为它是只读属性
  10. // 实现
  11. type myReadonly<T> = {
  12. readonly [K in keyof T]: T[K]
  13. }
  14. // 分析: 通过keyof拿到所有的key属性值组成联合类型, 然后通过in遍历类型,在属性值前面加上readonly, 值value则是 T[K]
  15. // 通过上面案例还可以实现可选类型
  16. type myOptional<T> = {
  17. [K in keyof T]?: T[K]
  18. }
复制代码
Exclude 语法: Exclude<T, U>, 返回 T 中不存在于 U 的部分
  1. // 回顾extends
  2. // // 联合类型, 表示如果T中的类型是U的子集, 那么返回never, 否则返回T, 这个过程可以理解为对T中的类型进行一次遍历, 每个类型都执行一次extends
  3. // type NonNullable1<T, U> = T extends U ? never : T
  4. // type NonExample = NonNullable1<null | string, null | undefined> // string
  5. // 自己实现Exclude
  6. type myExclude<T, U> = T extends U ? never : T
  7. // 测试
  8. // 分析: 对T也就是'a'|'b'遍历, a extends 'a'|'b', 返回never, 'b', 'a'|'c',返回'b', 所以上面的返回'b'
  9. type excludeExample = myExclude<'a' | 'b', 'a' | 'c'> // 'b'
复制代码
Partial 将传入的属性变为可选项
  1. interface Todo {
  2. title: string
  3. desc: string
  4. Done: boolean
  5. }
  6. type Partial<T> = {
  7. [P in keyof T]?: T[P]
  8. }
  9. type KeyOfExample1 = Partial<Todo>
  10. let keyofEx1: KeyOfExample1 = {
  11. title: '1'
  12. }
复制代码
-? 将可选项代表的 ?去掉, 将该类型变成必选项, 与之对应的还有一个+?,是将可选项变成必选项
  1. interface Todo {
  2. title: string
  3. desc: string
  4. Done: boolean
  5. }
  6. type Mutable<T> = {
  7. -readonly [P in keyof T]: T[P]
  8. }
  9. type mutableExample = Mutable<Readonly<Todo>>
  10. // 将Todo变成可读之后再变成可写
复制代码
Required 将传入的属性变成必选项
  1. type Required<T> = {
  2. [P in keyof T]-?: T[P]
  3. }
  4. class KeyCls {
  5. name?: string;
  6. age?: number;
  7. }
  8. const requiredExample: Required<KeyCls> = {
  9. name: "John",
  10. } // 报错
  11. const requiredExample2: Required<KeyCls> = {
  12. name: "John",
  13. age: 20,
  14. } // 正常
复制代码
Record<K, T> 将K中所有的属性转化为T类型
  1. type myRecord<K extends keyof any, T> = {
  2. [P in K]: T
  3. }
  4. enum Methods {
  5. GET = "get",
  6. POST = "post",
  7. DELETE = "delete",
  8. PUT = "put",
  9. }
  10. type IRouter = myRecord<Methods, (req: any, res: any) => void>
  11. // type IRouter = {
  12. //     get: (req: any, res: any) => void;
  13. //     post: (req: any, res: any) => void;
  14. //     delete: (req: any, res: any) => void;
  15. //     put: (req: any, res: any) => void;
  16. // }
复制代码
Omit 排除某些字段
  1. // 已经学习了Pick和Exclude, 则可以利用这两个实现Omit
  2. class KeyCls {
  3. name: string;
  4. age: number;
  5. }
  6. // 假设 T 为 KeyCls, K为name, 结果是
  7. // type myOmit<KeyCls, 'name'>
  8. // {  
  9. //    age: number;  
  10. // }
  11. // 只需要实现成这样就行了, 也就是获取到age
  12. type myOmit<T, K extends keyof T> = Pick<T, 'age'>
  13. // 排除name, 按照上面的 Exclude<'name' | 'age', 'name'> // 'age'
  14. type myOmit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
  15. // 测试
  16. type myOmitExample = myOmit<KeyCls, "name">;
  17. // type myOmitExample = {  
  18. //     age: number;  
  19. // }
复制代码
NonNullable<T>:作用是去掉 T 中的 null 和 undefined。T 为字面量/具体类型的联合类型
  1. // 4.8版本之前
  2. type NonNullable<T> = T extends null | undefined ? never : T;
  3. // 4.8版本之后
  4. type NonNullable<T> = T & {}
复制代码
infer 可以推荐一个类型变量, 相当于生命一个类型变量, 这个变量的类型取决于传入的泛型T
  1. type F<T> = T extends () => infer R ? R : T;
  2. type F1 = F<string> // string
  3. type TObj<T> = T extends { name: infer V, age: infer U } ? V : T
  4. type TObjExample2 = TObj<{
  5. name: number;
  6. age: string;
  7. }>; // number;
复制代码
ReturnType<T> 获取函数返回值的类型
  1. type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
  2. functin getUser() {
  3.     return {
  4.         name: 'xxx',
  5.         age: 20
  6.     }
  7. }
  8. type GetUserType = typeof getUser;
  9. // type GetUserType = () => {
  10. //   name: string;
  11. //   age: number;
  12. // }
  13. type ReturnUser = ReturnType<GetUserType>
  14. type ReturnUser = {
  15. //   name: string;
  16. //   age: number;
  17. // }
复制代码
以上就是TypeScript条件类型的详细内容,更多关于TypeScript条件类型的资料请关注脚本之家其它相关文章!

来源:https://www.jb51.net/javascript/292073gwm.htm
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具