TS系列之工具类型Partial、Required、Pick、Record详解,示例


前言

本片文章主要利用上一篇所学的keyof做一个延申与扩展的学习。在Typescript中,内部工具类型也同样使用到了keyof实现。所以现在来一起学习一下。keyof用法直通车🚗


在这里插入图片描述

一、Partial

描述:

Constructs a type with all properties of Type set to optional. This utility will return a type that represents all subsets of a given type.

中文翻译:

传入的泛型类型中所有的属性都变成可选的。

例如:
我们有一个ObjType的type类型,其中包含两个属性,name,age。Partial传入泛型中,得到新的Person类型。

type ObjType = {
  name: string;
  age: number;
}
type Person =  Partial<ObjType>

这样使用后就相当于定义了一个可选参数的类型例如:

type ObjType1 = {
  name?: string;
  age?: number;
}

使用方法:
定义几个person可以初始化定义不同对象的属性,如下。

const person1: Person = {name: '1', age: 1}
const person2: Person = {name: '1'}
const person3: Person = {age: 1}
const person4: Person = {}

原码:
type Partial = { [P in keyof T]?: T[P] | undefined; }

二、Required

描述:

Constructs a type consisting of all properties of Type set to required. The opposite of Partial.

中文翻译:

那么它的意思就是,要求传入的泛型类型的属性都是必输项。

例如:
我们有一个ObjType类型,它的每个属性都是可选参数,但是现在用Required转换类型,那么它的每一个属性都变成必输项。

type ObjType = {
  name?: string;
  age?: number;
}
type Person =  Required<ObjType>

这样使用后就相当于定义了一个必选参数的类型例如:

type ObjType = {
  name: string;
  age: number;
}

使用方法:
那么它的每一项都必须符合类型定义:

//正确:
const person1: Person = {name: '1', age: 1}
//错误:
const person2: Person = {name: '1'}
//Property 'age' is missing in type '{ name: string; }' but required in type 'Required<ObjType>'.ts(2741)
const person3: Person = {age: 1}
//Property 'name' is missing in type '{ age: number; }' but required in type 'Required<ObjType>'.ts(2741)
const person4: Person = {}
//Type '{}' is missing the following properties from type 'Required<ObjType>': name, agets(2739)

原码:
type Required = { [P in keyof T]-?: T[P]; }

三、Pick<Type, Keys>

描述:

Constructs a type by picking the set of properties Keys (string literal or union of string literals) from Type.

中文翻译:

从泛型Type中获取指定属性的类型,相当于得到的新类型只包含你所指定的泛型第二个参数的属性的类型。

例如:
还是上面类型,传入指定泛型类型,得到新的Person类型

type ObjType = {
  name: string;
  age: number;
}
type Person =  Pick<ObjType, 'name'>

这样使用后就相当于定义了一个指定类型例如:

Person就相当于type ObjType = {name: string}
使用方法:

//正确
type Person =  Pick<ObjType, 'name'>
const person2: Person = {name: '1'}
type Person =  Pick<ObjType, 'age'>
const person3: Person = {age: 1}
//报错:
const person2: Person = {name: '1', age: 1}
//Type '{ name: string; }' is not assignable to type 'Person'.
//Object literal may only specify known properties, and 'name' does not exist in type 'Person'.ts(2322)

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

四、Record<Keys, Type>

描述:

Constructs an object type whose property keys are Keys and whose property values are Type. This utility can be used to map the properties of a type to another type.

中文翻译:

接受两个泛型参数,第一个是对象属性key,第二个参数是key所对应的值的类型。

例如:
有个Test的接口,首先通过keyof获得它的联合类型,然后传入Record中的泛型中。得到新的类型

interface Test {
  person1: string;
  person2: string;
}
type Persons = keyof Test
type Person =  Record<Persons, ObjType>

这样相当于定义了一个新的类型如下:

type Person = {
  person1: {
    name: string;
    age: number;
  };
  person2: {
    name: string;
    age: number;
  }
}

使用方法:

const person1: Person = {
  person1: {
    name: '1',
    age: 1
  },
  person2: {
    name: '1',
    age: 1
  }
}
console.log(person1)

原码:
type Record<K extends string | number | symbol, T> = { [P in K]: T; }


总结

总结不易,如有问题欢迎指出。互相学习。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐