ts 内置工具类型(Partial、Pick、Record、Readonly、Exclude、Extract、Omit等)

  • 参考链接:https://blog.csdn.net/qq_43869822/article/details/121664818
  • typescript 源码可在包目录(如 node_modules)中 lib.es5.d.ts 文件中查看

概要

  • 可选 Partial 、必选 Required、只读 Readonly

  • 过滤、剔除:ExcludeExtractPickOmit

  • 约束对象的 key 和 value:Record

  • 去除 null 和 undefined:NonNullable

  • 函数参数类型:ParametersConstructorParameters

  • 函数返回值类型:ReturnTypeInstanceType

一、Partial

1、作用

生成一个 新类型,与老类型的 属性全部相同,但是都变为 可选

2、源码

type Partial<T> = { 
	[P in keyof T]?: T[P]; 
}
  • keyof T:拿出 T 中所有的 key,作为一个联合类型
  • in:表循环,类似于 for...in
  • P in keyof T:则 P 就代表了 T 中每个 key

3、使用

type Person = {
	name: string
	age: number
	sex: string
}

type Par = Partial<Person>
// 鼠标放上Par,可发现每个属性都加了一个 ?,如下:
// type Par = {
//   name?: string;
//   age?: number;
//   sex?: string;
// }

二、Required

1、作用

生成一个 新类型,与老类型的 属性全部相同,但是都变为 必选

2、源码

type Required<T> = {
  [P in keyof T]-?: T[P];
};
  • 与 Partial 相似,这里是 去掉 ?

3、使用

type Person = {
  name ?: string
  age: number
  sex ?: string
}

type Req = Required<Person>
// 鼠标放上Req,可发现每个属性都是必填,如下:
// type Req  = {
//   name: string;
//   age: number;
//   sex: string;
// }

三、Readonly

1、作用

生成一个 新类型,与老类型的 属性全部相同,但是都变为 只读

2、源码

type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};
  • 每个属性前增加关键字 readonly
  • 可选 特性会被保留

3、使用

type Person = {
  name: string 
  age: number
  sex?: string
}
type Read = Readonly<Person>
// 鼠标放上Read,可发现每个属性都是只读,如下:(sex仍然是可选)
// type Read = {
//   readonly name: string;
//   readonly age: number;
//   readonly sex?: string;
// }

四、Exclude

1、作用

  • 如果 T 是 U 的子类型则返回 never 不是则返回 T
  • 白话就是:从 T 出 剔除 U 包含的类型

2、源码

type Exclude<T, U> = T extends U ? never : T
  • T extends U:T 是 U 的子类型
  • T 的单个 去对比 U 的全部

3、使用

type A = string | number | boolean
type B = string | boolean | symbol
type C = string

type exc = Exclude<A, B>
// type exc = number

type exc2 = Exclude<A, C>
// type exc2 = number | boolean

五、Extract(与 Exclude 相反)

1、作用

  • 如果 T 是 U 的子类型则返回 T 不是则返回 never
  • 白话就是:从 T 中 选出 U 包含的类型

2、源码

type Extract<T, U> = T extends U ? T : never;

与 Exclude 相反,不做过多赘述

3、使用

type D = string | number | boolean
type E = number
type F = string | number | symbol

type ext = Extract<D, E>
// type ext = number

type ext2 = Extract<D, F>
// type ext2 = string | number

六、Pick

1、作用

生成一个 新类型,取出老类型中的 指定属性它对应的类型

2、源码

type Pick<T, K extends keyof T> = {
  [P in K]: T[P];
};
  • K extends keyof T:将 K 约束为 T 中的 key 构成,重要!

3、使用

type Person = {
  name: string
  age: number
  sex: string
}
type Pic = Pick<Person, 'name' | 'age'>
// 取出的就是指定 key 所组成的映射
// type Pic = {
//   name: string;
//   age: number;
// }

七、Omit(剔除)

1、作用

生成一个 新类型,从老类型中 剔除指定属性它对应的类型

2、源码

type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

// 也有这样的源码版本,是一个意思
type Omit<T, K extends string | number | symbol> = { 
  [P in Exclude<keyof T, K>]: T[P];
}
  • Pick 看似 相反,但不严格相反,因为这里的 K 不限制为 T 中的 key 构成
  • K extends keyof any 等价于 K extends string | number | symbol

3、使用

type Person3 = {
  name ?: string
  age: number
  readonly sex: string
  hobby: string
  height: number
}

// 第二个参数可以传无关的 'weight'
type per3 = Omit<Person3, 'hobby' | 'height' | 'weight'>
// type per3 = {
//   name?: string;
//   age: number;
//   readonly sex: string;
// }

八、Record

1、作用

限制 对象key 的取值、value 的类型

2、源码

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

3、使用

// 使用示例 1:第一个参数如果传具体的 key, 使用时每个 key 需要被具体设置
type Rec = Record<'A' | 'B' | 'C', number>
// type Rec = {
//   A: number;
//   B: number;
//   C: number;
// }
let obj: Rec = {
  A: 1,
  B: 2,
  C: 10
}


// 使用示例 2:第一个参数当然可以是 string | number | symbol 的任意类型联合的值
type Rec2 = Record<'A' | 2, boolean>
// type Rec2 = {
//   A: boolean;
//   2: boolean;
// }
let obj2: Rec2 = {
  A: true,
  2: false
}


// 使用示例 3:第一个参数如果传类型,使用时每个key都要对应上这个类型
type Rec3 = Record<string, number>
// type Rec3 = {
//   [x: string]: number
// }
let obj3: Rec3 = {
  A: 1,
  B: 2,
  C: 3
}


// 使用示例 4:第一个参数也可以传联合类型
type Rec4 = Record<number | symbol, boolean>
// type Rec4 = {
//   [x: number]: boolean;
//   [x: symbol]: boolean;
// }
let obj4: Rec4 = {
  1: true,
  [Symbol('111')]: false,
  2: false,
  // 'a': false // 报错,key类型不是 number 或 symbol
}


// 使用示例 5:路由信息的使用
type page = 'home' | 'login' | 'user'
type pageInfo = {
  title: string,
  needLogin: boolean
}
let obj5: Record<page, pageInfo> = {
  home: { title: '1111', needLogin: false },
  login: { title: '1111', needLogin: false },
  user: { title: '1111', needLogin: true },
}

九、NonNullable

1、作用

从泛型 T 中 排除掉 null 和 undefined

2、源码

type NonNullable<T> = T extends null | undefined ? never : T;

3、使用

type nonBefore = string | undefined | boolean | null | never

type non = NonNullable<nonBefore>
// type non = string | boolean

十、Parameters

1、作用

元组 的方式获得 函数的入参类型

2、源码

type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
  • infer 的作用单独用一篇学习,这里先记住,是将参数另外起名为 P

3、使用

type Para = Parameters<(name: string, age: number) => any>
// type Para = [name: string, age: number]
const para: Para = ['abc', 123]

十一、ConstructorParameters

1、作用

元祖 的方式获得 构造函数的入参类型

2、源码

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

3、使用

type Con = ConstructorParameters<new (name: string) => any>
// type Con = [name: string]
const con: Con = ['blue']


// 联合类型
type Con2 = ConstructorParameters<(new (name: string) => any) | (new (age: number) => number)>
// type Con2 = [name: string] | [age: number]
const con2: Con2 = ['blue']
const con22: Con2 = [123]


// 多个参数
type Con3 = ConstructorParameters<new (name: string, age: number) => any>
// type Con3 = [name: string, age: number]
const con3: Con3 = ['blue', 123]

十二、ReturnType

1、作用

获得 函数 返回值的类型

2、源码

type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;

3、使用

// 使用
type Ret = ReturnType<() => void>
// type Ret = void

type Ret2 = ReturnType<() => boolean>
// type Ret2 = boolean

type Ret3 = ReturnType<() => string | number>
// type Ret3 = string | number

十三、InstanceType

1、作用

获得 构造函数 返回值的类型

2、源码

type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any;

3、使用

// 使用
type Ins = InstanceType<new () => number>
// type Ins = number

End: 附13个type源码合集

/**
 * Make all properties in T optional
 */
type Partial<T> = {
  [P in keyof T]?: T[P];
};

/**
* Make all properties in T required
*/
type Required<T> = {
  [P in keyof T]-?: T[P];
};

/**
* Make all properties in T readonly
*/
type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

/**
* From T, pick a set of properties whose keys are in the union K
*/
type Pick<T, K extends keyof T> = {
  [P in K]: T[P];
};

/**
* Construct a type with a set of properties K of type T
*/
type Record<K extends keyof any, T> = {
  [P in K]: T;
};

/**
* Exclude from T those types that are assignable to U
*/
type Exclude<T, U> = T extends U ? never : T;

/**
* Extract from T those types that are assignable to U
*/
type Extract<T, U> = T extends U ? T : never;

/**
* Construct a type with the properties of T except for those in type K.
*/
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

/**
* Exclude null and undefined from T
*/
type NonNullable<T> = T extends null | undefined ? never : T;

/**
* Obtain the parameters of a function type in a tuple
*/
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;

/**
* Obtain the parameters of a constructor function type in a tuple
*/
type ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never;

/**
* Obtain the return type of a function type
*/
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;

/**
* Obtain the return type of a constructor function type
*/
type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any;

你可能感兴趣的:(Typescript,javascript,前端,typescript)