TypeScript类型体操挑战(八)

125 阅读1分钟

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

中等

Flatten

挑战要求

在线示例

type Flatten<T extends any[]> = 
  T extends [infer F, ...infer E] 
  ? [...(F extends any[] ? Flatten<F> 
  : [F]), ...Flatten<E>] : []
  • 要数组元素进行扁平化,那么就要对数组进行遍历,所以可以通过rest特性来进行迭代,也就是[infer F, ...infer E]
  • 迭代数组元素时,还要判断该元素是否为数组,,是就通过Flatten继续处理
  • 通过对数组元素进行递归处理,然后又通过...运算符进行解构,就可以达到扁平化的效果了

Append to object

挑战要求

在线示例

type AppendToObject<T, K extends string, V> = {
  [P in keyof T | K]: P extends keyof T ? T[P]: V;
}
  • 遍历对象类型T,然后将KTkey联合起来,也就有了keyof T | K
  • 而设置值类型时,只要对key进行判断就好了

Absolute

挑战要求

在线示例

type Absolute<T extends number | string | bigint, R = `${T}`> = R extends `-${infer E}` ? E : R;
  • 已经确定要返回的结果为字符串类型,所以可以通过定义一个泛型R通过字符串模板进行转换。这样使用泛型还可以简化代码,相当于占个位嘛
  • 之后就是通过条件类型将-去掉就好啦

String to Union

挑战要求

在线示例

type StringToUnion<T extends string, R = {}> = 
  T extends `${infer F}${infer E}` 
  ? StringToUnion<E, { [P in F]: F } & R> 
  : keyof R;
  • 我这里是把每个字符遍历出来,并组装成一个对象类型
  • 最后使用keyof来获取最终对象类型的键值的联合类型

我的写得复杂了点,在解答区看到一个简洁一些的:

type StrintToUnion<T extends string> = T extends `${infer Letter}${infer Rest}`
  ? Letter | StrintToUnion<Rest>
  : never;
  • 就是直接用联合类型的运算符|来拼接所有的字符类型