typescript复杂用法举例

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,忽略T中的某些属性,对于父组件传入子组件值很有用:

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 }
}

你可能感兴趣的:(typescript)