模式匹配做提取 数组类型 提取数组第一个元素的类型 
1 2 3 type  GetFirst<Arr extends  unknown[]> = Arr extends  [infer First, ...unknown[]]  ? First   : never ; 
提取数组最后一个元素的类型 
1 2 3 type  GetLast<Arr extends  unknown[]> = Arr extends  [...unknown[], infer Last]  ? Last   : never ; 
取去掉最后一个元素的数组 
1 2 3 4 5 type  PopArr<Arr extends  unknown[]> = Arr extends  []  ? []   : Arr extends  [...infer Rest, unknown]   ? Rest   : never ; 
字符串类型 字符串是否以某个特定字符开头 
1 2 3 4 type  StartWidth<  Str extends  string ,   Prefix extends  String  > = Str extends  `${Prefix} ${string } `  ? true  : false ; 
将字符串中某个特定的部分替换成别的字符串 
1 2 3 4 5 6 7 type  ReplaceStr<  Str extends  string ,   From extends  string ,   To extends  string  > = Str extends  `${infer Prefix} ${From} ${infer Suffix} `    ? `${Prefix} ${To} ${Suffix} `    : Str; 
字符串去除右空格 
1 2 3 4 5 6 type  TrimStrRight<Str extends  string > = Str extends  `${infer Rest} ${    | " "    | "\n"    | "\t" } `  ? TrimStrRight<Rest>   : Str; 
函数类型 提取函数参数的类型 
1 2 3 4 5 type  GetParameters<Func extends  Function > = Func extends  (  ...args: infer Args ) => unknown   ? Args   : never ; 
提取函数返回值的类型 
1 2 3 4 5 type  GetReturnType<Func extends  Function > = Func extends  (  ...args: any [] ) => infer ReturnType   ? ReturnType   : never ; 
构造器 提取构造器参数的类型 
1 2 3 4 type  GetInstanceParameters<ConstructorType extends  new  (...args: any ) => any > =  ConstructorType extends  new  (...args: infer ParametersType) => any      ? ParametersType     : never ; 
提取构造器返回值类型 
1 2 3 4 type  GetInstanceReturnType<ConstructorType extends  new  (...args: any ) => any > =  ConstructorType extends  new  (...args: any ) => infer InstanceType     ? InstanceType     : never ; 
索引类型 提取 props 中 ref 值的类型 
1 2 3 4 5 type  GetRefProps<Props> = "ref"  extends  keyof Props  ? Props extends  { ref?: infer Value | undefined  }     ? Value     : never    : never ; 
重新构造做变换 TypeScript 的 type、infer、类型参数声明的变量都不能修改,想对类型做各种变换产生新的类型就需要重新构造。
数组类型的构造 给数组/元组添加新类型 
1 type  Push<Arr extends  unknown[], Ele> = [...Arr, Ele];
元组重组 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 type  tuple1 = [1 , 2 ];type  tuple2 = ["guang" , "dong" ];type  tuple = [[1 , "guang" ], [2 , "dong" ]];type  Zip<One extends  unknown[], Other extends  unknown[]> = One extends  [  infer OneFirst,   ...infer OneRest ]   ? Other extends  [infer OtherFirst, ...infer OtherRest]     ? [[OneFirst, OtherFirst], ...Zip<OneRest, OtherRest>]     : []   : []; 
字符串类型的构造 将字符串首字母大写 
1 2 3 4 type  CapitalizeStr<Str extends  string > =  Str extends  `${infer First} ${infer Rest} `      ? `${Uppercase<First>} ${Rest} `      : Str; 
将字符串下划线转驼峰 
```tstype CamelCase<Str extends string> = Str extends${infer Left}_${infer Right}${infer Rest}?${Left}${Uppercase}${CamelCase}`   Str; 1 2 3 4 5 6 7 8 **删除字符串子串** ```ts type DropSubStr<Str extends string, SubStr extends string> =     Str extends `${infer Prefix}${SubStr}${infer Suffix}`         ? DropSubStr<`${Prefix}${Suffix}`, SubStr>         : Str; 
函数类型的构造 给函数添加一个参数 
1 2 3 4 5 type  AppendArgument<Func extends  Function , Arg> = Func extends  (  ...args: infer Args ) => infer ReturnType   ? (...args: [...Args, Arg] ) =>  ReturnType   : never ; 
索引类型的构造 索引类型是聚合多个元素的类型。比如 class 和对象都是索引类型。索引类型的元素的类型只能是 string、number 或者 Symbol 等类型。
索引类型的每个元素的类型可以添加修饰符:readonly(只读)、?(可选)。
映射类型语法 
1 2 3 type  Mapping<Obj extends  object > = {  [Key in  keyof Obj]: Obj[Key]; }; 
用 as 做重映射改变索引类型的 Key 转成大写 
1 2 3 type  UppercaseKey<Obj extends  object > = {  [Key in  keyof Obj as  Uppercase<Key & string >]: Obj[Key]; }; 
因为这里索引的类型可能是 string、number 或 symbol 类型,但是这里转成大写只能是限定为 string。
 
TS 内置高级类型 Record 
1 type  Record<K extends  string  | number  | symbol, T> = { [P in  K]: T };
UppercaseKey 重写版:用 Record 来约束索引类型而不是 object 
1 2 3 type  UppercaseKey<Obj extends  Record<string , any >> = {  [Key in  keyof Obj as  Uppercase<Key & string >]: Obj[Key]; }; 
给索引类型添加只读的高级类型 
1 2 3 type  ToReadonly<T> = {  readonly  [Key in  keyof T]: T[Key]; }; 
给索引类型添加可选的高级类型 
1 2 3 type  ToPartial<T> = {  [Key in  keyof T]?: T[Key]; }; 
给索引类型去掉只读修饰符 
1 2 3 type  ToMutable<T> = {  -readonly  [Key in  keyof T]: T[Key]; }; 
给索引类型去掉可选修饰符 
1 2 3 type  ToRequired<T> = {  [Key in  keyof T]-?: T[Key]; }; 
返回特定值的类型的索引类型 
1 2 3 type  FilterByValueType<Obj extends  Record<string , any >, ValueType> = {  [Key in  keyof Obj as  Obj[Key] extends  ValueType ? Key : never ]: Obj[Key]; }; 
递归复用做循环 Promise 的递归复用 提取 Promise 值的类型 
1 2 3 4 5 6 7 type  DeepPromiseValueType<P extends  Promise <unknown>> = P extends  Promise <  infer ValueType >   ? ValueType extends  Promise <unknown>     ? DeepPromiseValueType<ValueType>     : ValueType   : never ; 
提取 Promise 值的类型简化版 
1 2 3 type  DeepPromiseValueType<T> = T extends  Promise <infer ValueType>  ? DeepPromiseValueType<ValueType>   : never ; 
数组类型的递归 反转元组 
1 2 3 4 5 6 type  ReversrArr<Arr extends  unknown[]> = Arr extends  [  infer First,   ...infer Rest ]   ? [...ReversrArr<Rest>, First]   : Arr; 
查找元素 
1 2 3 4 5 6 7 8 9 10 type  Includes<Arr extends  unknown[], FindItem> = Arr extends  [  infer First,   ...infer Rest ]   ? IsEqual<First, FindItem> extends  true      ? true      : Includes<Rest, FindItem>   : false ; type  IsEqual<A, B> = (A extends  B ? true  : false ) &  (B extends  A ? true  : false ); 
删除元素 
1 2 3 4 5 6 7 8 9 10 11 type  RemoveItem<  Arr extends  unknown[],   Item,   Result extends  unknown[] = [] > = Arr extends  [infer First, ...infer Rest]   ? IsEqual<First, Item> extends  true      ? RemoveItem<Rest, Item, Result>     : RemoveItem<Rest, Item, [...Result, First]>   : Result; type  IsEqual<A, B> = (A extends  B ? true  : false ) &  (B extends  A ? true  : false ); 
构造指定类型的数组 
1 2 3 4 5 type  BuildArray<  Length extends  number ,   Ele = unknown,   Arr extends  unknown[] = [] > = Arr["length" ] extends  Length ? Arr : BuildArray<Length, Ele, [...Arr, Ele]>; 
字符串类型的递归 替换子串 
1 2 3 4 5 6 7 type  ReplaceAll<  Str extends  string ,   From extends  string ,   To extends  string  > = Str extends  `${infer Left} ${From} ${infer Right} `    ? `${Left} ${To} ${ReplaceAll<Right, From, To>} `    : Str; 
提取字符做联合类型 
1 2 3 4 type  StringToUnion<Str extends  string > =  Str extends  `{infer First}${infer Rest} `      ? First | StringToUnion<Rest>     : never ; 
反转字符串 
1 2 3 type  ReverseStr<Str extends  string > = Str extends  `${infer First} ${infer Rest} `   ? `${ReverseStr<Rest>} ${First} `    : Str; 
对象类型的递归 深度递归 
1 2 3 4 5 6 7 8 9 type  DeepToReadonly<T extends  Record<string , any >> = T extends  any   ? {       readonly  [Key in  keyof T]: T[Key] extends  Object          ? T[Key] extends  Function            ? T[Key]           : DeepToReadonly<T[Key]>         : T[Key];     }   : never ; 
数组长度做计算 数组长度实现加减乘除 加法 
1 2 3 4 5 6 7 8 9 10 type  BuildArray<  Length extends  number ,   Ele = unknown,   Arr extends  unknown[] = [] > = Arr["length" ] extends  Length ? Arr : BuildArray<Length, Ele, [...Arr, Ele]>; type  Add<Num1 extends  number , Num2 extends  number > = [  ...BuildArray<Num1>,   ...BuildArray<Num2> ]["length" ]; 
减法 
1 2 3 4 5 6 type  Subtract<  Num1 extends  number ,   Num2 extends  number  > = BuildArray<Num1> extends  [...BuildArray<Num2>, ...infer Rest]   ? Rest["length" ]   : never ; 
乘法 
1 2 3 4 5 6 7 type  Multiple<  Num1 extends  number ,   Num2 extends  number ,   ResultArr extends  unknown[] = [] > = Num2 extends  0    ? ResultArr["length" ]   : Multiple<Num1, Subtract<Num2, 1 >, [...ResultArr, ...BuildArray<Num1>]>; 
除法 
1 2 3 4 5 6 7 type  Divide<  Num1 extends  number ,   Num2 extends  number ,   ResultArr extends  unknown[] = [] > = Num1 extends  0    ? ResultArr["length" ]   : Divide<Subtract<Num1, Num2>, Num2, [...ResultArr, unknown]>; 
数组长度实现计数 计算字符串长度 
1 2 3 4 5 6 type  StrLen<  Str extends  string ,   CountArr extends  unknown[] = [] > = Str extends  `${string } ${infer Rest} `    ? StrLen<Rest, [...CountArr, unknown]>   : CountArr["length" ]; 
比较 2 个数值谁更大 
1 2 3 4 5 6 7 8 9 10 11 type  GreaterThan<  Num1 extends  number ,   Num2 extends  number ,   CountArr extends  unknown[] = [] > = Num1 extends  Num2   ? false    : CountArr["length" ] extends  Num2   ? true    : CountArr["length" ] extends  Num1   ? false    : GreaterThan<Num1, Num2, [...CountArr, unknown]>; 
实现斐波那契数列 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 type  FibonacciLoop<  PrevArr extends  unknown[],   CurrentArr extends  unknown[],   IndexArr extends  unknown[] = [],   Num extends  number  = 1  > = IndexArr["length" ] extends  Num   ? CurrentArr["length" ]   : FibonacciLoop<       CurrentArr,       [...PrevArr, ...CurrentArr],       [...IndexArr, unknown],       Num     >; type  Fibonacci<Num extends  number > = FibonacciLoop<[1 ], [], [], Num>;
聚合分散可简化 分布式条件类型 当类型参数为联合类型,并且在条件类型左边直接引用该类型参数的时候,TypeScript 会把每一个元素单独传入来做类型运算,最后再合并成联合类型,这种语法叫做分布式条件类型。
1 2 3 4 type  Union = "a"  | "b"  | "c" ;type  UppercaseA<Item extends  string > = Item extends  "a"   ? Uppercase<Item>   : Item; 
这和联合类型遇到字符串时的处理一样:
1 2 3 type  Union = "a"  | "b" ;type  str = `${Union} ~` ;
数组转联合类型 1 2 3 type  Arr = ["a" , "b" , "c" ];type  UnionArr = Arr[number ];
判断是否是联合类型 1 type  isUnion<A, B = A> = A extends  A ? ([B] extends  [A] ? false  : true ) : never ;
当 A 是联合类型时:
A extends A 这种写法是为了触发分布式条件类型,让每个类型单独传入处理的,没别的意义。 
A extends A 和 [A] extends [A] 是不同的处理,前者是单个类型和整个类型做判断,后者两边都是整个联合类型,因为只有 extends 左边直接是类型参数才会触发分布式条件类型。 
 
BEM 1 2 3 4 5 type  BEM<  Block extends  string ,   Element extends  string [],   Modifiers extends  string [] > = `${Block} __${Element[number ]} --${Modifiers[number ]} ` ; 
全组合 1 2 3 4 5 6 7 8 9 type  Combination<A extends  string , B extends  string > =    A | B | `${A} ${B} `  | `${B} ${A} `  type  AllCombinations<A extends  string , B extends  string  = A> =    A extens A         ? Combination<A, AllCombinations<Exclude<B, A>>>         : never ; 
特殊特性要记清 IsAny any 类型与任何类型的交叉都是 any,也就是 1 & any 结果是 any。
1 type  IsAny<T> = "a"  extends  1  & T ? true  : false ;
IsEqual 1 2 3 4 5 6 7 8 9 10 type  IsEqual<A, B> = (A extends  B ? true  : false ) &  (B extends  A ? true  : false ); type  IsEqual2<A, B> = (<T>() =>  T extends  A ? 1  : 2 ) extends  <  T >() =>  T extends  B ? 1  : 2    ? true    : false ; 
IsUnion 1 type  IsUnion<A, B> = A extends  A ? ([B] extends  [A] ? false  : true ) : never ;
IsNever never 在条件类型中也比较特殊,如果条件类型左边是类型参数,并且传入的是 never,那么直接返回 never。
1 2 3 4 5 6 type  TestNever<T> = T extends  number  ? 1  : 2 ;type  result = TestNever<never >;type  IsNever<T> = [T] extends  [never ] ? true  : false ;
除此之外,any 在条件类型中也比较特殊,如果类型参数为 any,会直接返回 trueType 和 falseType 的合并。
1 2 3 type  TestAny<T> = T extends  number  ? 1  : 2 ;type  result = TestAny<any >;
IsTuple 元组类型的 length 是数字字面量,而数组的 length 是 number。
1 2 3 4 5 6 7 8 9 type  IsTuple<T> = T extends  [...infer Eles]  ? NotEqual<Ele["length" ], number >   : false ; type  NotEqual<A, B> = (<T>() =>  T extends  A ? 1  : 2 ) extends  <  T >() =>  T extends  B ? 1  : 2    ? false    : true ; 
UnionToIntersection 联合类型转交叉类型。
1 2 3 4 5 type  UnionToIntersecion<U> = (U extends  U ? (x: U ) =>  unknown : never ) extends  (  x: infer R ) => unknown   ? R   : never ; 
GetOptional 提取索引类型中的可选索引。
1 2 3 4 5 6 type  GetOptional<Obj extends  Record<string , any >> = {  [Key in  keyof Obj as  {} extends  Pick<Obj, Key> ? Key : never ]: Obj[Key]; }; type  Pick<T, K extends  keyof T> = { [P in  K]: T[P] };
GetRequired 提取索引类型中的非可选索引构造成新的索引类型。
1 2 3 type  GetRequired<Obj extends  Record<string , any >> = {  [Key in  keyof Obj as  {} extends  Pick<Obj, Key> ? never  : Key]: Obj[Key]; }; 
RemoveIndexSignature 过滤掉索引类型中的可索引签名,构造成一个新的索引类型。
1 2 3 type  RemoveIndexSignature<Obj extends  Record<string , any >> = {  [Key in  keyof Obj as  Key extends  `${infer Str} `  ? Str : never ]: Obj[Key]; }; 
ClassPublicProps 过滤 class 的 public 属性。
1 2 3 type  ClassPublicProps<Obj extends  Record<string , any >> = {  [Key in  keyof Obj]: Obj[Key]; }; 
as const TypeScript 默认推导出来的类型并不是字面量类型。
1 2 3 4 5 6 7 8 9 const  obj = {  a: 1 ,   b: 2 , }; type  objType = typeof  obj;
如果想要推到出字面量,就需要用 as const:
1 2 3 4 5 6 7 const  arr = [1 , 2 , 3 ];type  arrType = typeof  arr;const  arr2 = [1 , 2 , 3 ] as  const ;type  arrType2 = typeof  arr2;
反转 3 个元素的元组类型,需要加上 readonly 才能匹配成功。
1 2 3 type  ReverseArr<Arr> = Arr extends  readonly  [infer A, infer B, infer C]  ? [C, B, A]   : never ; 
练一练 实现 ParseQueryString 将 ‘a=1&b=2&c=3’ 转成 {a: 1, b: 2, c: 3}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 type  ParseQueryString<Str extends  string > =  Str extends  `${infer Param} &${infer Rest} `      ? MergeParams<ParseParams<Param>, ParseQueryString<Rest>>     : ParseParam<Str>; type  ParseParams<Param extends  string > =  Param extends  `${infer Key} =${infer Value} `      ? {         [K in  Key]: Value;       }     : Record<string , any >; type  MergeParams<  OneParam extends  Record<string , any >,   OtherParam extends  Record<string , any > > = {   [Key in  keyof OneParam | keyof OtherParam]: Key extends  keyof OneParam     ? Key extends  keyof OtherParam       ? MergeValue<OneParam[Key], OtherParam[Key]>       : OneParam[Key]     : Key extends  keyof OtherParam     ? OtherParam[Key]     : never ; }; type  MergeValue<One, Other> = One extends  Other  ? One   : Other extends  unknown[]   ? [One, ...Other]   : [One, Other]; 
TS 内置的高级类型 Parameters 提取函数类型的参数类型
1 2 3 4 5 type  Parameters<T extends  (...args: any ) => any > = T extends  (  ...args: infer P ) => any    ? P   : never ; 
ReturnType 提取函数类型的返回值类型
1 2 3 4 5 type  ReturnType<T extends  (...args: any ) => any > = T extends  (  ...args: any  ) => infer R   ? R   : never ; 
ConstructorParameters 提取构造函数的参数类型
1 2 3 4 5 type  ConstructorParameters<T extends  new  (...ars: any ) => any > = T extends  new  (  ...args: infer P ) => any    ? P   : never ; 
InstanceType 提取构造器返回值类型
1 2 3 4 5 type  InstanceType<T extends  new  (...ars: any ) => any > = T extends  new  (  ...ars: any  ) => infer R   ? R   : any ; 
ThisParameterType 提取函数参数中 this 的类型
1 2 3 type  ThisParameterType<T> = T extends  (this : infer U, ...args: any []) => any   ? U   : unknown; 
OmitThisParameter 去除函数参数中的 this 类型,并且返回一个新的类型
1 2 3 4 5 6 type  OmitThisParameter<T> =    unknown extends  ThisParameterType<T>         ? T         : T extends  (...args: infer A) => infer R             ? (...args: A) => infer R             : T; 
Partial 把索引类型的所有索引变成可选类型
1 2 3 type  Partial<T> = {  [P in  keyof T]?: T[P]; }; 
Required 把索引类型里可选索引改成必选索引
1 2 3 type  Required<T> = {  [P in  keyof T]-?: T[P]; }; 
Readonly 索引类型的索引添加只读
1 2 3 type  Readonly<T> = {  readonly  [P in  keyof T]: T[P]; }; 
Pick 过滤出指定的索引类型
1 2 3 type  Pick<T, K extends  keyof T> = {  [P in  K]: T[P]; }; 
Record 创建索引类型
keyof any 会返回 string | number | symbol
 
1 2 3 type  Record<K extends  keyof any , T> = {  [P in  K]: T; }; 
如果 Record 里的第一个参数是 string | number | symbol,那么创建的就是索引签名索引类型:
1 2 3 4 type  RecordRes = Record<string , number >;
Exclude 去掉联合类型中的某些类型,即取差集
联合类型当作为类型参数出现在条件类型左边时,会被分散成单个类型传入,这叫做分布式条件类型。
1 type  Exclude<T, U> = T extends  U ? never  : T;
提取联合类型中的某些类型,即取交集
1 type  Extract<T, U> = T extends  U ? T : never ;
Omit 去掉某部分索引类型的索引构成新索引类型
1 type  Omit<T, K in  keyof any > = Pick<T, EXclude<keyof T, K>>;
Awaited 提取 Promise 的返回值类型
1 2 3 4 5 6 7 8 type  Awaited<T> =    T extends  null  | undefined          ? T         : T extends  object  & { then(onfulfilled: infer F): any }             ? F extends  ((value, infer V, ...ars: any  ) =>  any )                 ? Awaited<V>                 : never              : T; 
NonNullable 判断是否是空类型,即不是 null 或 undefined
1 type  NonNullable<T> = T extends  null  | unfefined ? never  : T;
Uppercase、Lowercase、Capitalize、Uncapitalize 这几个类型分别是实现大写、小写、首字母大写、去掉首字母大写的。
综合实战 KebabCaseToCamelCase ‘aa-bb-cc’ 这种是 KebabCase,而 ‘aaBbCc’ 这种是 CamelCase
1 2 3 4 type  KebabCaseToCamelCase<Str extends  string > =  Str extends  `${infer Item} -${infer Rest} `      ? `${Item} ${KebabCaseToCamelCase<Capitalize<Rest>>} `      : Str; 
CamelCaseToKebabCase 1 2 3 4 5 6 type  CamelCaseToKebabCase<Str extends  string > =  Str extends  `${infer First} ${infer Rest} `      ? First extends  Lowercase<First>       ? `${First} ${CamelCaseToKebabCase<Rest>} `        : `-${Lowercase<First>} ${CamelCaseToKebabCase<Rest>} `      : Str; 
Chunk 对数组做分组,比如 1、2、3、4、5 的数组,每两个为 1 组,那就可以分为 1、2 和 3、4 以及 5 这三个 Chunk。
1 2 3 4 5 6 7 8 9 10 type  Chunk<  Arr extends  unknown[],   ItemLen extends  number ,   CurItem extends  unknown[] = [],   Res extends  unknown[] = [] > = Arr extends  [infer First, ...infer Rest]   ? CurItem["length" ] extends  ItemLen     ? Chunk<Rest, ItemLen, [First], [...Res, CurItem]>     : Chunk<Rest, ItemLen, [...CurItem, First], Res>   : [...Res, CurItem]; 
TupleToNestedObject 根据数组类型,比如 [‘a’, ‘b’, ‘c’] 的元组类型,再加上值的类型 ‘xxx’,构造出这样的索引类型:
1 2 3 4 5 6 7 {   a: {     b: {       c: "xxx" ;     }   } } 
1 2 3 4 5 6 7 8 9 10 11 12 type  TupleToNestedObject<Tuple extends  unknown[], ValueType> = Tuple extends  [  infer First,   ...infer Rest ]   ? {       [Key in  First as  Key extends  keyof any          ? Key         : never ]: Rest extends  unknown[]         ? TupleToNestedObject<Rest, ValueType>         : ValueType;     }   : ValueType; 
PartialObjectPropByKeys 把一个索引类型的某些 Key 转为 可选的,其余的 Key 不变。
1 2 3 4 5 6 7 8 9 10 11 type  PartialObjectPropByKeys<  Obj extends  Record<string , any >,   Key extends  keyof any  > = Partial<Pick<Obj, Extract<keyof Obj, Key>>> & Omit<Obj, Key>; type  PartialObjectPropByKeys2<  Obj extends  Record<string , any >,   KeyType extends  keyof any  > = {   [Key in  keyof Obj as  Key extends  KeyType ? Key? : Key]: Obj[Key]; }; 
函数重载的三种写法 第一种 
1 2 3 4 5 function  add (a: number , b: number  ): number function  add (a: string , b: string  ): string function  add (a: any , b: any  )   return  a + b; } 
第二种 
1 2 3 4 5 interface  Func {  (a: number , b: number ): number ;   (a: string , b: string ): string ; } const  add: Func = (a: any , b: any  ) =>  a + b;
第三种 
1 2 type  Func = ((a: number , b: number  ) =>  number ) & ((a: string , b: string ): string )const  add: Func = (a: any , b: any  ) =>  a + b;
UnionToTuple 将联合类型转成元组。
1 2 3 4 5 6 7 8 9 10 11 12 type  UnionToTuple<T> = UnionToIntersection<  T extends  any  ? () =>  T : never  > extends  () => infer ReturnType   ? [...UnionToTuple<Exclude<T, ReturnType>>, ReturnType]   : []; type  UnionToIntersection<U> = (  U extends  U ? (x: U ) =>  unknown : never  ) extends  (x: infer R) => unknown   ? R   : never ; 
join 实现一个类似的效果,将:
1 2 const  res = join("-" )("guang" , "and" , "dong" );
join 代码实现 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 declare  function  join <Delimiter  extends  string >(  delimiter: Delimiter Items  extends  string []>(...parts: Items ) => JoinType <Items , Delimiter >type  JoinType<  Items extends  any [],   Delimiter extends  string ,   Result extends  string  = ""  > = Items extends  [infer First, ...infer Rest]   ? JoinType<Rest, Delimiter, `${Result} ${First & string } -` >   : RemoveLastDelimiter<Result>; type  RemoveLastDelimiter<Str extends  string > = Str extends  `${infer Rest} -`   ? Rest   : Str; 
AllKeyPath 拿到一个索引类型的所有 key 的路径。
1 2 3 4 5 6 7 type  AllKeyPath<Obj extends  Record<string , any >> = {  [Key in  keyof Obj]: Key extends  string      ? Obj[Key] extends  Record<string , any >       ? Key | `${Key} .${AllKeyPath<Obj[Key]>} `        : Key     : never ; }[keyof Obj]; 
Defaultize 实现这样一个高级类型,对 A、B 两个索引类型做合并,如果是只有 A 中有的不变,如果是 A、B 都有的就变为可选,只有 B 中有的也变为可选。
1 2 3 type  Defaultize<A, B> = Pick<A, Exclude<keyof A, keyof B>> &  Partial<Pick<A, Extract<keyof A, keyof B>>> &   Partial<Pick<B, Exclude<keyof B, keyof A>>>; 
infer extends 枚举值转联合类型 以下会把枚举的数值类型转成字符串类型。
1 2 3 4 5 6 7 enum  Code {  a = 111 ,   b = 222 ,   c = "abc" , } type  res = `${Code} ` ;
StrToNum 使用 infer extends 后就就可以正常使用了。
1 2 3 4 5 6 7 8 enum  Code {  a = 111 ,   b = 222 ,   c = "abc" , } type  StrToNum<Str> = Str extends  `${infer Num extends  number } `  ? Num : Str;type  res = StrToNum<`${Code} ` >;