keyof
keyof 与 Object.keys略有相似,keyof 是取 interface 的键,而 keyof 取到键后会保存为联合类型。
interface iUserInfo{name: string;age: number;}type keys = keyof iUserInfo;
使用场景
function getValue(o: object, key: string) {return o[key];}const obj1 = { name: '张三', age: 18 };const name = getValue(obj1, 'name');
function getValue<T extends Object, K extends keyof T>(o: T, key: K): T[K] {return o[key];}const obj1 = { name: '张三', age: 18 };const a = getValue(obj1, 'name');
in
in用于取联合类型的值。主要用于数组和对象的构造。不能用于 interface。
type name = 'firstName' | 'lastName';type TName = {[key in name]: string;};
infer实例
typescript不能不掌握的高级特性(二)
使用 infer 获取函数参数 Parameters
定义了一个函数类型 TArea,现在要实现将函数的参数类型取出来,我们该怎么做呢?
type TArea = (width: number, height: number) => number;type params = Parameters<TArea>;// Parameters 是ts内置的方法
使用 infer 获取函数返回值 ReturnType
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R? R: any;
获取实例类型 InstanceType
type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R? R: any;
获取构造函数类型 ConstructorParameters
type ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never;
获取参数 this 参数 ThisParameterType
type ThisParameterType<T> = T extends (this: infer U, ...args: any[]) => any? U: unknown;
剔除 this 参数 OmitThisParameter
Partial
Partial 将属性变为可选属性。举个栗子,iUser 这个接口 name 和 age 是必须的,但是同时又有另一个接口 iOptionUser,接口属性完全一样,只是里面的 name 和 age 是可选的
实现
type Partial<T> = {[P in keyof T]?: T[P];};
场景
interface iUser {name: string;age: number;}interface iOptionUser {name?: string;age?: number;}type iOptionUser = Partial<iUser>
Required
Required和Partial方法正好相反,是将属性变成必须。方法同样非常简单,可以这样实现(该方法已内置)
实现
type Required<T> = {[P in keyof T]-?: T[P];};
场景
interface iOptionUser {name?: string;age?: number;}type iUser = Required<iOptionUser>
Readonly
Readonly是将属性变成只读。方法同样非常简单,可以这样实现(该方法已内置)
type Readonly<T> = {readonly [P in keyof T]: T[P];};
interface iOptionUser {name?: string;age?: number;}type user = Readonly<iOptionUser>
Pick
源码
type Pick<T, K extends keyof T> = {[P in K]: T[P];};
适用场景
interface iDog {name: string,age: number;bark: () => void}type animal = Pick<iDog, "name" | "age">;
Record
源码
type Record<K extends keyof any, T> = {[P in K]: T;};
Exclude
从类型 T 中剔除所有可以赋值给 U 的属性,然后构造一个类型。主要用于联合类型。
源码
type Exclude<T, U> = T extends U ? never : T;
场景
type excludeA = Exclude<'a' | "b" | "c", "a">
Extract
源码
type Extract<T, U> = T extends U ? T : never;
场景
type extractA = Extract<'a' | "b" | "c", "a">
Omit
主要用于剔除interface中的部分属性。 比如接口iUser包含name、age、firstName、lastName、location属性,而接口iUser2不包含location属性,我们可以使用前面提到的Pick实现,但这样会比较复杂,所以有了Omit 操作符。
interface iUser {name: string;age: number;firstName: string;lastName: string;location: string;}/*interface iUser2 {name: string;age: number;firstName: string;lastName: string;}*/type iUser2 = Omit<iUser, "firstName">
