# TS关键字
一些进阶关键字,如果不懂只需要记住有这个东西就行。
keyof
keyof
关键字可以获取某种类型的所有键,其返回类型是联合类型。
type A = keyof any // type A = string | number | symbol
type User = {
name: string
age: number
}
type Key = keyof User // type Key = number | string
// 直接获取对象中的所有类型
let obj = {
name: 'xiaoming',
age: 18
}
type Key = keyof typeof obj // type Key = number | string
搭配 in 遍历 keyof里联合类型获取key值
interface Data {
name: string,
age: number,
sex: string
}
// 使用 key in 循环 Data接口,遍历成一个可选的类型别名
type Options<T extends object> = {
[Key in keyof T]?:T[Key]
// readonly [Key in keyof T]:T[Key] 或者
}
type C = Options<Data>
// type C = {
// name?: string | undefined;
// age?: number | undefined;
// sex?: string | undefined;
// }
Partial
将某个类型里的属性全部变为可选项,只可以作为类型使用。
interface Data {
name: string,
age: number,
sex: string
}
type A = Partial<Data>
// type A = {
// name?: string | undefined;
// age?: number | undefined;
// sex?: string | undefined;
// }
type Person = {
name: string,
age: number,
sex: boolean
}
type P = Partial<Person>
// type P = {
// name?: string | undefined;
// age?: number | undefined;
// sex?: boolean | undefined;
// }
其原理就是利用 keyof in 循环替换一遍。
type Partial<T> = {
[P in keyof T]?: T[P]
}
Readonly
将某个类型里的属性全部变为只读项。
type Person = {
name: string,
age: number,
sex: boolean
}
type P = Readonly<Person>
// type P = {
// readonly name: string;
// readonly age: number;
// readonly sex: string;
// }
实现原理
type Readonly<T> = {
readonly [P in keyof T]?: T[P]
}
Pick 从某个类型里的属性取出几个想要的。
type Person = {
name: string,
age: number,
sex: boolean
}
type P = Pick<Person, 'age' | 'name'>
// type P = {
// age: number;
// name: string;
// }
实现原理
type Pick<T, K extends keyof T> = {
[key in K]: T[key]
}
Record 将传入的两个类型组装成新的类型,第一个可以是联合类型。
type Person = {
name: string,
age: number,
sex: boolean
}
type K = 'A' | 'B' | 'C'
type R = Record<K, Person>
// 组装成新的类型
// type R = {
// A: Person;
// B: Person;
// C: Person;
// }
let r:R = {
A: {name: 'aaa', age: 18, sex: false},
B: {name: 'bbb', age: 18, sex: false},
C: {name: 'ccc', age: 18, sex: false}
}
// 联合keyof使用
type P = keyof Person
type R = Record<P, Person>
// 获取Person里所有的key
// type R = {
// name: Person;
// age: Person;
// sex: Person;
// }
let p:R = {
name: {name: 'aaa', age: 18, sex: false},
age: {name: 'bbb', age: 18, sex: false},
sex: {name: 'ccc', age: 18, sex: false}
}
实现原理
// string | number | symbol
type Record<K extends keyof any, T> = {
[P in K]: T
}
从上面的关键字可以看出,通过泛型和keyof我们可以组装成我们想要的其他类型数据。
infer
infer作为extends的子语句使用,infer可以在extends的条件语句中推断待推断的类型。infer 后面定义一个名字,这个名字就代表剩下被推断的所有类型。
// 推断数组中的某些类型
// infer推断每一个元素
type Arr = ['a', 'b', 'c']
type El<T extends any[]> = T extends [infer a, infer b, infer c] ? a : []
type a = El<Arr> // type a = "a"
// 推断出第一个元素
type Arr = ['a', 'b', 'c']
type First<T extends any[]> = T extends [infer first, ...any[]] ? first : []
type first = First<Arr> // type first = "a"
// 推断出最后一个元素
type Arr = ['a', 'b', 'c']
type Last<T extends any[]> = T extends [...any[], infer last] ? last : []
type last = Last<Arr> // type last = "c"
// 删除最后一个
type Arr = ['a', 'b', 'c']
type Pop<T extends any[]> = T extends [infer rest, unknown] ? rest : []
type pop = Pop<Arr> // type pop = ['a', 'b']
// 数组取反
type Arr = [1, 2, 3, 4]
type Reverse<T extends any[]> = T extends [infer first, ...infer rest] ? [...Reverse<rest>, first] : T
type rArr = Reverse<Arr> // type rArr = [4, 3, 2, 1]