Typescript内置工具类型(一)

130 阅读3分钟

调试环境:TypeScript Playground

1. Partial

作用:Partial接收一个泛型类型Type,并将Type所有属性都设置为可选的,返回构造的新类型。

使用

type a = {
  name: string
  age: number
}

type b = Partial<a>

源码实现

type Partial<T> = { [P in keyof T]?: T[P]; }

2. Required

作用:Required接收一个泛型类型Type,并将Type所有属性都设置为必选的,返回构造的新类型(Required的作用与Partial相反)。

使用

type a = {
  name?: string
  age?: number
}

type b = Required<a>

源码实现

type Partial<T> = { [P in keyof T]-?: T[P]; }

3. Readonly

作用:Readonly接收一个泛型类型Type,并将Type所有属性都设置为只读的,返回构造的新类型, 新类型的属性不可再进行分配。

使用

type a = {
  name: string
  age: number
}

const user: Readonly<a> = { name: 'xiaoming', age: 30 }
user.age = 100 // Cannot assign to 'age' because it is a read-only property

源码实现

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

4. Record

作用:构造一个对象类型,其属性键为Keys,属性值为Type

使用

interface User {
    name: string
    age: number
}

type UserName = 'xiaoming' | 'xiaohong' | 'xiaohuang'

const users: Record<UserName, User> = {
    xiaoming: { name: 'ming', age: 23 },
    xiaohong: { name: 'hong', age: 24 },
    xiaohuang: { name: 'huang', age: 25 }
}

源码实现

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

5. Pick

作用: 从类型Type中选择一组属性Keys来创建类型。

使用

interface User {
    name: string
    age: number
}

type nameOnly = Pick<User,'name'>

const users: nameOnly = { 
    name: 'ming', 
    age: 23 // Error: Object literal may only specify known properties, and 'age' does not exist in type 'nameOnly'.
}

源码实现

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

6. Omit

作用: 与Pick相反,Omit是从Type中选取所有Keys属性然后删除构造一个新类型。

interface User {
    name: string
    age: number
}

type nameOnly = Omit<User,'age'>

const users: nameOnly = { 
    name: 'ming', 
    age: 23,// Error: Object literal may only specify known properties, and 'age' does not exist in type 'nameOnly'.
}

源码实现

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

7. Exclude

作用: 从联合类型UnionType中排除ExcludedMembers类型然后返回一个新类型。

type a = 1 | 2 | 3

type b = 3 | 4

type c = Exclude<a, b> // 1 | 2

源码实现

type Exclude<T, U> = T extends U ? never : T

8. Extract

作用: 从联合类型Type中提取Union类型然后返回一个新类型。

type a = 1 | 2 | 3

type b = 3 | 4

type c = Extract<a, b> // 3

源码实现

type Exclude<T, U> = T extends U ? T : never

9. NonNullable

作用: 通过从Type中排除nullundefined来构造一个类型。

type a = string | null | undefined

type b = NonNullable<a> // string

源码实现

type NonNullable<T> = T & {}

10. Parameters

作用: 接受一个函数类型, 将函数的参数处理成一个元组类型。

function createStudent(sno: string, name: string, age: number) {
    return { sno, name, age }
}

type CreateStudentParams = Parameters<typeof createStudent>

const createStuParams: CreateStudentParams = ['111', 'x', 30]
const stu1 = createStudent(...createStuParams)

源码实现

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

扩展:

  • Parameters接收的泛型必须是一个函数类型,但是作为顶级类型any和底层类型never, Typescript对其有特殊的处理。
    type T1 = Parameters<any>; // unknown[]  
    type T2 = Parameters<never>; // never
    
  • Typescript中定义的Function也不能被parameters接收,看Function 的实现就知道了。
    ts
    type T3 = Parameters<Function>; // error  
    
    Function的实现:
    interface Function {  
        readonly name: string;  
    }
    
  • 如果函数是重载函数,那么返回的是最后一个函数的参数组成的元组类型
    declare function stringOrNum(x: string): number;
    declare function stringOrNum(x: number): string;
    declare function stringOrNum(x: string | number): string | number;
    
    type T1 = Parameters<typeof stringOrNum>; // [x: string | number]
    

11. ReturnType

作用: 获取函数类型的返回值类型。

function getUser() {
    return { name: 'x', age: 30 }
}

type User = ReturnType<typeof getUser>

const user: User = { name: 'y', age: 26 }

源码实现

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

扩展:

  • Parameters类型一样,接收的泛型必须是一个函数类型
  • 泛型是anynever的情况
    type T1 = ReturnType<any>; // any  
    type T2 = ReturnType<never>; // never
    
  • Function不能被ReturnType接收
  • 如果函数是重载函数,那么返回的是最后一个函数的返回类型。