类型运算

118 阅读2分钟

1、条件:extends ?

TypeScript 里的条件判断是 extends ? :,叫做条件类型(Conditional Type)比如:

作用:经过一系列类型运算逻辑后,返回新的类型。

type isString14<T> = T extends string ? true : false;
type res14_1 = isString14<'111'>;//true
type res14_2 = isString14<2>;//false

2、infer

  1. infer只能在条件类型的 extends 子句中使用
  2. infer得到的类型只能在true语句中使用, 即X中使用
//推断数组(或者元组)的类型
type InferArray<T> = T extends (infer U)[] ? U : never;
type I0 = InferArray<[number, string]>; // string | number
type I1 = InferArray<string[]>; // string
type I2 = InferArray<number[]>; // number


//1、推断数组(或者元组)第一个元素的类型
type InferFirst<T extends unknown[]> = T extends [infer P, ...infer _] ? P : never
//[infer P, ... infer _]`中`infer P获取的`是第一个元素的类型,而`...infer _`获取的是数组其他剩余元素的数组类型;
type I3 = InferFirst<[3, 2, 1]>; // 3


//2、推断函数类型的参数
type InferParameters<T extends Function> = T extends (...args: infer R) => any ? R : never;
type I5 = InferParameters<((arg1: string, arg2: number) => void)>; // [string, number]
//`...args` 代表的是函数参数组成的元组, `infer R`代表的就是推断出来的这个函数参数组成的元组的类型。

//3、推断函数类型的返回值
type InferReturnType<T extends Function> = T extends (...args: any) => infer R ? R : never;
type I6 = InferReturnType<() => string>; // string
//和前面的`推断函数类型的参数`类似,`=>` 后面的`infer R`代表的就是推断出来的函数的返回值类型。

//4、推断字符串字面量类型的第一个字符对应的字面量类型
type InferString<T extends string> = T extends `${infer First}${infer _}` ? First : [];
type I8 = InferString<"Johnny">; // J

//5、获取对象的value的类型
//获取所有的value的类型
type Obj1 = { name: string, age: number }
type get1<T> = T extends { name: infer U, age: infer C } ? [U, C] : T
type C = get1<Obj1>//[string,number]这样的一个元祖
//只获取单个value的类型
type Obj1 = { name: string, age: number }
type get2<T> = T extends { name: infer U } ? U : T
type D = get2<Obj1> //只是一个string类型
// 当然我们也可以有这样的写法
type get3<T> = T extends { name: infer U, age: infer U } ? U : T
type E = get3<Obj1> //string|number 的联合类型

3、联合:|

联合类型(Union)类似 js 里的或运算符 |,但是作用于类型,代表类型可以是几个类型之一。

type Union = 1 | 2 | 3;

4、交叉:&

交叉类型(Intersection)类似 js 中的与运算符 &,但是作用于类型,代表对类型做合并。

interface Person { name: string } 
interface People { sex: string } 
type PersonMan = Person & People
//这里就相当于
type PersonMan = {name: string, sex: string }
\\注意,同一类型可以合并,不同的类型没法合并,会被舍弃:

参考链接:

juejin.cn/book/704752…

www.jianshu.com/p/707a304d7… blog.csdn.net/huangfengnt…

blog.csdn.net/xihuanLilia…