TypeScript-类型转换
Smoothness 2023/6/12 TypeScript
本文介绍TypeScript
中各种类型如果转换。
# 类型转换-重新构造
TypeScript
的 type
、infer
、类型参数声明的变量都不能修改,想对类型做各种变换产生新的类型就需要重新构造
。
# 数组类型的重新构造
Push
:给元组类型再添加一些类型type arr = [1, 2, 3] type Push<Arr extends unknown[], last> = [...Arr, last] type push = Push<arr, 4>
1
2
3Unshift
:在前面添加type arr = [1, 2, 3] type Unshift<Arr extends unknown[], first> = [first, ...Arr] type unshift = Unshift<arr, 0>
1
2
3
# 字符串类型的重新构造
CapitalizeStr
:首字母大写type str = 'yellow' type CapitalizeStr<Str extends string> = Str extends `${infer First}${infer All}` ? `${Uppercase<First>}${All}` : Str type CapitalizeStrCase = CapitalizeStr<str>
1
2
3CamelCase
:转驼峰type str1 = 'yellow_yellow_yellow_yellow_yellow' type CamelCase<Str extends string> = Str extends `${infer first}_${infer next}${infer rest}` ? `${first}${Uppercase<next>}${CamelCase<rest>}`: Str type CamelCaseCase = CamelCase<str1>
1
2
3DropSubStr
:删除一段字符type str2 = 'hello !!!!!' type DropSubStr<Str extends string, Substr extends string> = Str extends `${infer Prefix}${Substr}${infer Suffix}` ? DropSubStr<`${Prefix}${Suffix}`, Substr> : Str type DropSubStrCase = DropSubStr<str2, '!'>
1
2
3
# 函数类型的重新构造
AppendArgument
:添加参数type func1 = (name: string, age: number) => void type AppendArgument<Func extends Function, addParams> = Func extends (...arg: infer Args) => infer ReturnType ? (...args: [...Args, addParams]) => ReturnType : never type AppendArgumentCase = AppendArgument<func1, 'gender'>
1
2
3
# 索引类型的重新构造
Mapping
:映射修改type map = { a: 1, b: 2, c:3 } type Mapping<map extends object> = { [Key in keyof map]: [map[Key], map[Key]] } type MappingCase = Mapping<map>
1
2
3
4
5
6
7
8
9UppercaseKey
:把索引变成大写type map = { a: 1, b: 2, c:3 } type UppercaseKey<Obj extends object> = { [Key in keyof Obj as Uppercase<Key & string>]: Obj[Key] } type UppercaseKeyCase = UppercaseKey<map> // Record 可以约束 type UppercaseKeyRecord<Obj extends Record<string, any>> = { [Key in keyof Obj as Uppercase<Key & string>]: Obj[Key] }
1
2
3
4
5
6
7
8
9
10
11
12
13ToReadonly
:添加readonly
type map = { a: 1, b: 2, c:3 } type ToReadonly<T> = { readonly [Key in keyof T]: T[Key]; } type ToReadonlyCase = ToReadonly<map>
1
2
3
4
5
6
7
8
9ToPartial
:索引可选type map = { a: 1, b: 2, c:3 } type ToPartial<T> = { [Key in keyof T]?: T[Key]; } type ToPartialCase = ToPartial<map>
1
2
3
4
5
6
7
8
9ToMutable
:去掉readonly
type map = { a: 1, b: 2, c:3 } type ToMutable<T> = { -readonly [Key in keyof T]: T[Key]; } type ToMutableCase = ToMutable<ToReadonly<map>>
1
2
3
4
5
6
7
8
9ToRequired
:去掉可选type map = { a: 1, b: 2, c:3 } type ToRequired<T> = { [Key in keyof T]-?: T[Key]; } type ToRequiredCase = ToRequired<ToPartial<map>>
1
2
3
4
5
6
7
8
9FilterByValueType
:过滤属性interface obj { name: 'zs', age: 12, run: () => void } type FilterByValueType<T extends Record<string, any>, valueType> = { [Key in keyof T as T[Key] extends valueType ? Key : never]: T[Key] } type FilterByValueTypeCase1 = FilterByValueType<obj, number> type FilterByValueTypeCase2 = FilterByValueType<obj, number | string> type FilterByValueTypeCase3 = FilterByValueType<obj, () => any>
1
2
3
4
5
6
7
8
9
10
11
12