1.实现一个从对象上取出指定属性的pick函数:
用到索引类型查询操作符keyof、索引访问操作符[]
const user = {
username: 'lee',
id: 46093049239239,
role: 'vip'
}
const pick = <T, K extends keyof T>(o: T, names: K[]): T[K][] => {
return names.map(n => o[n]);
}
const res = pick(user, ['username', 'role']);
2.实现将接口中的成员全部变成可选/必选的:
属性全可选:
用到映射类型[K in Keys](以下为实现,可使用直接Partial)
type partial<T> = { [K in keyof T]?: T[K] }
// 使用
type partialUser = partial<User>
如果要做到深层属性可选,要用到类型递归
type DeepPartial<T> = {
[U in keyof T]?: T[U] extends object
? DeepPartial<T[U]>
: T[U]
}
属性全必选:
+ -关键字用于映射类型中给属性添加修饰符,-?代表可选变为必选,-readonly代表将只读变为非只读
type Required<T> = { [P in keyof T]-?: T[P] }
3.实现传入类型为字符串,返回字符串,否则为布尔值的函数声明:
条件类型进行类型关系检测T extends U ? X : Y
declare function f<T>(x: T): T extends string ? string : boolean;
4.获取接口中类型为Function的属性名:
interface Part {
id: number;
name: string;
subparts: Part[];
updatePart(newName: string): void;
}
type FunctionPropertyNames<T> = { [K in keyof T]: T[K] extends Function ? K : never }[keyof T]
// R类型updatePart
type R = FunctionPropertyNames<Part>;
5.Omit
type Omit<T, K> = Pick<T, Exclude<keyof T, K>>
type Foo = Omit<{name: string; age: number}, 'name'>
6.运用Record实现对象属性名和属性值的校验:
type Car = 'Audi' | 'BMW' |
type CarList = Record<Car, {age: number}>
const cars: CarList = {
Audi: { age : 119 },
BMW: { age: 113 }
}