主题
重新构造
type、infer、类型参数声明的变量都不能修改,想对类型做各种变换产生新的类型就需要重新构造
数组
把以下两个元组合并成另一个元组
typescript
type a = [1, 2]
type b = ['1', '2']
type c = [[1, '1'], [2, '2']]
则可以如下重新构造
typescript
type Zip<One extends [unknown, unknown], Two extends [unknown, unknown]> =
One extends [infer OneF, infer OneT]
? Two extends [infer TwoF, infer TwoT]
? [[OneF, TwoF], [OneT, TwoT]]
: []
: []
字符串
实现 dong_dong 到 dongDong 的变换
小写到大写的转换可以用到内置高级类型 Uppercase
typescript
type camelCase<S extends string> =
S extends `${infer Prefix}_${infer C}${infer Rest}`
? `${Prefix}${Uppercase<C>}${Rest}`
: S
函数
在已有的函数类型上添加一个参数
typescript
type AppendArgument<Func extends Function, Arg> =
Func extends (...args: infer Args) => infer ReturnType
? (...args: [...Args, Arg]) => ReturnType
: never
索引
- 重新构造 value
typescript
type Mapping<Obj extends object> = {
[Key in keyof Obj]: [Obj[Key], Obj[Key], Obj[Key]]
}
- 重新构造 key,被称为 重映射
typescript
type UppercaseKey<Obj extends object> = {
[Key in keyof Obj as Uppercase<Key & string>]: Obj[Key]
}
因为索引可能为 string、number、symbol 类型,而这里只能接受 string 类型,所以要 & string,也就是取索引中 string 的部分
索引类型的约束用的 object,其实更语义化一点推荐用
Record<string, any>
typescripttype UppercaseKey<Obj extends Record<string, any>> = { [Key in keyof Obj as Uppercase<Key & string>]: Obj[Key] }