TypeScript类型体操挑战(六)

113 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

中等

Trim Left

挑战要求

在线示例

type Space = ' ' | '\n' | '\t';

type TrimLeft<S extends string> = S extends `${Space}${infer R}` ? TrimLeft<R> : S;
  • 主要就是利用模板字符串来进行拼接,然后作为判断条件,从而推断类型
  • 通过递归的方式,将空格\n\t等字符排除掉,就能获取到最终结果了

关于模板字符串的文档请看Template Literal Types

Capitalize

挑战要求

在线示例

type Mapping = {
  'a': 'A',
  'b': 'B',
  'c': 'C',
  'd': 'D',
  'e': 'E',
  'f': 'F',
  'g': 'G',
  'h': 'H',
  'i': 'I',
  'j': 'J',
  'k': 'K',
  'l': 'L',
  'm': 'M',
  'n': 'N',
  'o': 'O',
  'p': 'P',
  'q': 'Q',
  'r': 'R',
  's': 'S',
  't': 'T',
  'u': 'U',
  'v': 'V',
  'w': 'W',
  'x': 'X',
  'y': 'Y',
  'z': 'Z',
}

type MyCapitalize<S extends string> =  
S extends `${infer F}${infer R}` 
? `${F extends keyof Mapping ? Mapping[F] : F}${R}` 
: S;
  • 通过模板字符串 `${infer F}${infer R}`可以获取到首字母
  • 事先定义好一个大小写字母的映射类型MappingF作为键就可以获取到对应的大写字母了

Replace

挑战要求

在线示例

type Replace<S extends string, From extends string, To extends string> = 
From extends '' 
? S 
: S extends `${infer F}${From}${infer E}` 
  ? `${F}${To}${E}`
  : S;
  • 主要还是基于模板字符串,然后搭配条件类型来进行处理,跟Capitalize 是一样的道理

ReplaceAll

挑战要求

在线示例

type ReplaceAll<S extends string, From extends string, To extends string> =
From extends '' 
? S 
: S extends `${infer F}${From}${infer E}` 
  ? `${F}${To}${ReplaceAll<E, From, To>}`
  : S;
  • Replace是类似的,只不过不要进行递归处理,将所有的字符进行替换
  • 但需要注意的是,匹配后的字符,不应该再传递下去进行递归处理,所以就有了`${F}${To}${ReplaceAll<E, From, To>}`,这样就会将匹配到的字符一个接一个地进行替换了

追加参数

挑战要求

在线示例

type AppendArgument<Fn, A> = Fn extends (...args: infer P) => infer R ? (...x: [...P, A]) => R : Fn;
  • 先利用条件判断推断出Fn的参数与返回值类型
  • 然后通过rest参数来将新函数的参数组合起来就行了