模式匹配

字符串可以与正则做模式匹配,找到匹配的部分提取子组,之后可以用 $1, $2 … 这种方式引用匹配的子组

  1. 'abc'.replace(/a(b)c/, '$1$1$1'); // 'b,b,b'

Typescript 的类型也可以做模式匹配
比如一个 Promise 类型,相提取 value 的类型:

  1. type p = Promise<'xxxx'>;
  2. type GetValueType<P> = P extends Promise<infer Value> ? Value : never;

通过 extends 对传入的类型参数 P 做模式匹配,其中值的类型是需要提取。
通过 infer 声明一个局部的变量 Value 来保存,如果匹配就返回匹配到的 Value,否则返回 never 代表没有匹配到。
image.png

Typescript 类型的模式匹配是通过 extends 对类型参数做匹配,结果保存到通过 infer 声明的局部类型变量里,如果匹配就能从该局部变量里拿到提取出的类型。

数组类型的模式匹配

  1. type arr = [1, 2, 3];
  2. // First [1, 2, 3] -> 1
  3. type GetFirst<Arr extends unknown[]> =
  4. Arr extends [infer First, ...unknown[]] ? First : never;
  5. // Last [1, 2, 3] -> 3
  6. type GetLast<Arr extends unknown[]> =
  7. Arr extends [...unknown[], infer Last] ? Last : never;
  8. // PopArr [1, 2, 3] -> [1, 2]
  9. type PopArr<Arr extends unknown[]> =
  10. Arr extends [] ? []
  11. : Arr extends [...infer Rest, unknown] ? Rest : never;
  12. // ShiftArr [1, 2, 3] -> [2, 3]
  13. type ShiftArr<Arr extends unknown[]> =
  14. Arr extends [] ? []
  15. : Arr extends [unknown, ...infer Rest] ? Rest : never;

字符串类型的模式匹配

  1. // StartsWith
  2. type StartsWith<Str extends string, Prefix extends string> =
  3. Str extends `${Prefix}${string}` ? true : false;
  4. // Replace
  5. type ReplaceStr<
  6. Str extends string,
  7. From extends string,
  8. To extends string
  9. > = Str extends `${infer Prefix}${From}${infer Suffix}`
  10. ? `${Prefix}${To}${Suffix}` : Str;
  11. // TrimRight
  12. type TrimRight<Str extends string> =
  13. Str extends `${infer Rest}${' ' | '\n' | '\t'}`
  14. ? TrimRight<Rest> : Str;
  15. // TrimLeft
  16. type TrimLeft<Str extends string> =
  17. Str extends `${' ' | '\n' | '\t'}${infer Rest}`
  18. ? TrimLeft<Rest> : Str;
  19. // Trim
  20. type Trim<Str extends string> = TrimRight<TrimLeft<Str>>;

函数的模式匹配

  1. // GetParameters
  2. type GetParameters<Func extends Funciton> =
  3. Func extends (...args: infer Args) => unknown ? Args : never;
  4. // GetReturnType
  5. type GetReturnType<Func extends Function> =
  6. Func extends (...args: unknown[]) => infer ReturnType
  7. ? ReturnType : never;