TS技巧----工具包汇总

317 阅读3分钟

官方内置库

Partial: 包装对象可选 。

type Partial<T> = { // 全部变可选 已经内置了
  [P in keyof T]?: T[P];
};

interface User {
  id: number;
  age: number;
  name: string;
};


// 相当于: type PartialUser = { id?: number; age?: number; name?: string; }
type PartialUser = Partial<User>

Required 去除可选, 变成必选择

 
type Required<T> = { // 已经内置不用自己定义
	[K in keyof T]-?: T[K];
}

interface User {
  id: number;
  name?: string;
};
// 相当于 { id: number;  name: string; }
type RequiredUser = Required<User>

Readonly 变成只读,不能更改

type Readonly<T> = {
	readonly [K in keyof T]: T[K];
}

Pick 选取传入的键值

type Pick<T, K extends keyof T> =  {
	[P in K]: T[P]
}

interface User {
  id: number;
  age: number;
  name: string;
};

// 相当于: type PickUser = { id: number; age: number; }
type PickUser = Pick<User, "id" | "age">

Exclude : 不保留传入的键值名

never: 表示永远不会出现的联合类型中,可以通过keyof过滤掉,通常被用来将收窄联合类型或是接口,或者作为条件类型判断的兜底。 如果U在T内,则不出现U

// 都是内置了
type Exclude<T, U> =  T extends U ? never : T;

type Val = 'a' | 'b' | 'c'
// 因为X没出现在Val内,所以等于 type A = 'x'
type A = Exclude<'x' | 'a', Val>



  
  

Extract: 保留传入的键值名和Exclude 相反

type Extract<T extends Object, U extends keyof any> =  T extends U ? T: never

type Val = 'a' | 'b' | 'c'
// 因为a出现在Val里,所以b=a
type b = Extract<'a' | 'd', Val>

Omit

对原接口的成员,剔除掉传入的联合类型成员。通过exclude过滤掉,通过Pick获取对应的对象及值

type Omit<T extends Object,  K extends keyof any> = Pick<T, Exclude<keyof T, K>>
  
interface User {
  id: number
  age: number
  name?: string
}
// 等于 { age: number; name: string; }
type OmitUser = Omit<User, 'id'>

Record

通常用于生成以联合类型为键名(Keys),键值类型为Type的新接口。Record 后面的泛型就是对象键和值的类型

type Record<K extends keyof any, T> = {
	[P in K]: T;
}

// 比如我要定义一个User的对象类型,可以这么写

interface User {
  id: number
  age: number
  name?: string
}

type UserKey = string

const UserObj: Record<UserKey, User> = {
  user_1: {
    id: 1,
    age: 18,
    name: '小明',
  },
  user_2: {
    id: 2,
    age: 18,
    name: '张三',
  },
}

社区类型工具

这一部分的工具类型大多来自于utility-types ,其作者同时还有 react-redux-typescript-guide typesafe-actions这两个优秀作品。

同时,也推荐 type-fest 这个库,和上面相比更加接地气一些。其作者的作品...,我保证你直接或间接的使用过(如果不信,一定要去看看,我刚看到的时候是真的震惊的不行)。

可以阅读社区写入的typescript的丰富工具库

infer概念同步

表示在 extends 条件语句中待推断的类型变量。可以用在获取方法参数的规则,用于判断传参变量是否允合

type ParamType<T>  =  T extends (...args: infer P) => any ? P : T;

在这个条件语句 T extends (...args: infer P) => any ? P : T 中,infer P 表示待推断的函数参数。

整句表示为:如果 T 能赋值给 (...args: infer P) => any,则结果是 (...args: infer P) => any 类型中的参数 P,否则返回为 T。

interface User {
	id: number
  age: number
  name?: string
}

type Func =  (user: User) => void;
type Param =  ParamType<Func>; //  Param = [User]; 是个数组,如果有多个参数按顺序出现在数组里
const a:Param = [{id:1,age:18,name:'张三'}]

type Test =  ParamType<string>; string;

参考

【1】ata.alibaba-inc.com/articles/21…

【2】jkchao.github.io/typescript-…

【3】github.com/piotrwitek/…

【4】 github.com/sindresorhu…