TypeScript 内置工具类型全解析,先收藏吃灰

TypeScript 内置工具类型全解析,先收藏吃灰

前端 TypeScript

01 Awaited<Type>

递归展开 Promise 兑现后(fulfilled)返回的类型。Awaited 会递归推导出 async/await 方法返回的类型,或是 Promise .then() 中返回的类型。

定义:

type Awaited<T> = T extends null | undefined
  ? T
  : T extends object & {
      then(onfulfilled: infer F, ...args: infer _): any
    }
  ? F extends (value: infer V, ...args: infer _) => any
    ? any
    : any
  : any

示例:

// type A = string
type A = Awaited<Promise<string>>

// type B = number
type B = Awaited<Promise<Promise<number>>>

// type C = number | boolean
type C = Awaited<boolean | Promise<number>>

// type D = boolean
type D = Awaited<boolean>

// type E = string | Date
type E = Awaited<Date | Promise<Promise<string>>>

type FakePromise = { then: () => string }
// type F = never
type F = Awaited<FakePromise>

02 Partial<Type>

根据 Type 的类型构造出一个属性一致但所有属性都设置为可选的类型。

定义:

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

示例:

interface Todo {
  title: string
  description: string
}
// type PartialTodo = {
//   title?: string | undefined;
//   description?: string | undefined;
// }
type PartialTodo = Partial<Todo>

03 Required<Type>

根据 Type 的属性构造出一个属性一致,但所有属性都设置为必选的类型。功能与 Partial<Type> 相反。

定义:

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

示例:

interface Todo {
  title: string
  description?: string
}
// type RequiredTodo = {
//   title: string;
//   description: string;
// }
type RequiredTodo = Required<Todo>

04 Readonly<Type>

根据 Type 的属性构造出一个属性一致,但所有属性都设置为只读的类型。

定义:

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

示例:

interface Todo {
  title: string
  description?: string
}
// type ReadonlyTodo = {
//   readonly title: string;
//   readonly description?: string | undefined;
// }
type ReadonlyTodo = Readonly<Todo>

05 Record<Keys, Type>

可以很方便地构造出一个对象类型,其属性的键是 Keys,其属性的值为 Type。也可以用于将一种类型的属性映射到另一种类型。

定义:

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

示例:

// type A = {
//   [x: string]: any
// }
type A = Record<string, any>

interface Todo {
  title: string
  description: string
}
// type B = {
//   title: number;
//   description: number;
// }
type B = Record<keyof Todo, number>

interface CatInfo {
  age: number
  breed: string
}
type CatName = 'Zhangsan' | 'Lisi' | 'Wanger'
// type Cats = {
//   Zhangsan: CatInfo;
//   Lisi: CatInfo;
//   Wanger: CatInfo;
// }
type Cats = Record<CatName, CatInfo>

06 Pick<Type, Keys>

Type 中选取 Keys 中的表述的属性,构造出新的类型。

Keys 为字符串或字符串的并集。

定义:

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

示例:

interface Todo {
  title: string
  description: string
  completed: boolean
}
// type TodoPreview = {
//   title: string
//   completed: boolean
// }
type TodoPreview = Pick<Todo, 'title' | 'completed'>

07 Omit<Type, Keys>

Type 中剔除 Keys 中的表述的属性,用剩下的属性构建出新的类型。

定义:

type Omit<T, K extends string | number | symbol> = {
  [P in Exclude<keyof T, K>]: T[P]
}

示例:

interface Todo {
  title: string
  description: string
  completed: boolean
  createdAt: number
}
// type TodoPreview = {
//   title: string
//   completed: boolean
//   createdAt: number
// }
type TodoPreview = Omit<Todo, 'description'>

08 Exclude<UnionType, ExcludedMembers>

UnionType 中剔除 ExcludedMembers 中的表述的成员,用剩下的成员构建出新的类型。

定义:

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

示例:

type UnionType = 'a' | 'b' | 'c' | 'd'

// type A = "b" | "c" | "d"
type A = Exclude<UnionType, 'a'>

// type B = "c" | "d"
type B = Exclude<UnionType, 'a' | 'b'>

// type C = string | number
type C = Exclude<string | number | (() => void), Function>

09 Extract<Type, Union>

Type 中提取所有可分配给 Union 的成员来构建出新的类型。

定义:

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

示例:

// type A = "a"
type A = Extract<'a' | 'b' | 'c', 'a' | 'f'>

// type B = () => void
type B = Extract<string | number | (() => void), Function>

10 NonNullable<Type>

Type 中排除 nullundefined 后,构造出新的类型。

定义:

type NonNullable<T> = T & {}

示例:

// type A = string | number
type A = NonNullable<string | number | undefined>

// type B = string[]
type B = NonNullable<string[] | null | undefined>

11 Parameters<Type>

Type 这个函数类型的参数中使用的类型,构造出一个元组类型。

定义:

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

示例:

function func(arg: { a: number; b: string }): void

// type A = []
type A = Parameters<() => string>

// type B = [s: string
type B = Parameters<(s: string) => void>

// type C = [arg: unknown]
type C = Parameters<<T>(arg: T) => T>

// type D = [
//   arg: {
//     a: number
//     b: string
//   }
// ]
type D = Parameters<typeof func>

// type E = unknown[]
type E = Parameters<any>

// type F = never
type F = Parameters<never>

// type G = never
type G = Parameters<string>

// type H = never
type H = Parameters<Function>

12 ConstructorParameters<Type>

Type 这个构造函数类型的参数中使用的类型,构造出一个新的元组类型或数组类型。如果 Type 不是函数,构造出的类型将是 never

定义:

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

示例:

// type A = [message?: string | undefined, options?: ErrorOptions | undefined]
type A = ConstructorParameters<ErrorConstructor>

// type B = string[]
type B = ConstructorParameters<FunctionConstructor>

// type C = [pattern: string | RegExp, flags?: string | undefined]
type C = ConstructorParameters<RegExpConstructor>

// type D = unknown[]
type D = ConstructorParameters<any>

// type E = never
type E = ConstructorParameters<Function>

13 ReturnType<Type>

根据 Type 这个函数类型的返回类型,构造出新的类型。

定义:

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

示例:

function func(): { a: number; b: string }

// type A = string
type A = ReturnType<() => string>

// type B = void
type B = ReturnType<(s: string) => void>

// type C = unknown
type C = ReturnType<<T>() => T>

// type D = number[]
type D = ReturnType<<T extends U, U extends number[]>() => T>

// type E = {
//   a: number
//   b: string
// }
type E = ReturnType<typeof func>

// type F = any
type F = ReturnType<any>

// type G = never
type G = ReturnType<never>

// type H = any
type H = ReturnType<string>

// type I = any
type I = ReturnType<Function>

14 InstanceType<Type>

根据 Type 中构造函数的实例类型,构造出新的类型。

定义:

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

示例:

class C {
  x = 0
  y = 0
}

// type A = C
type A = InstanceType<typeof C>

// type B = any
type B = InstanceType<any>

// type C = never
type C = InstanceType<never>

// type D = any
type D = InstanceType<string>

// type E = any
type E = InstanceType<Function>

15 ThisParameterType<Type>

Type 这个函数类型中提取 this 参数的类型,如果函数类型没有 this 参数,则为 unknown

定义:

type ThisParameterType<T> = T extends (this: infer U, ...args: never) => any
  ? U
  : unknown

示例:

function toHex(this: Number) {
  return this.toString(16)
}
// type A = Number
type A = ThisParameterType<typeof toHex>

function numberToString(n: A) {
  return toHex.apply(n)
}

16 OmitThisParameter<Type>

Type 中删除 this 参数。如果 Type 没有显式声明 this 参数,结果直接返回 Type 保持不动。否则,将从 Type 创建一个没有 this 参数的新的函数类型。

定义:

type OmitThisParameter<T> = unknown extends ThisParameterType<T>
  ? T
  : T extends (...args: infer A) => infer R
  ? (...args: A) => R
  : T

示例:

function toHex(this: Number) {
  return this.toString(16)
}
// const fiveToHex: () => string
const fiveToHex: OmitThisParameter<typeof toHex> = toHex.bind(5)

17 ThisType<Type>

ThisType 不返回转换后的类型,它只充当上下文中 this 类型的标记。

必须启用 noImplicitThis 编译选项才能使用此工具类型。

定义:

interface ThisType<T> { }

示例:

type ObjectDescriptor<D, M> = {
  data?: D
  methods?: M & ThisType<D & M> // 标记 methods 中的 ‘this’ 类型是: D & M
}

function makeObject<D, M>(desc: ObjectDescriptor<D, M>): D & M {
  const data: object = desc.data || {}
  const methods: object = desc.methods || {}
  return { ...data, ...methods } as D & M
}

const obj = makeObject({
  data: { x: 0, y: 0 },
  methods: {
    moveBy(dx: number, dy: number) {
      this.x += dx // 强制输入 this
      this.y += dy // 强制输入 this

      // 15, 25
      console.log(this.x, this.y)
    }
  }
})

obj.x = 10
obj.y = 20
obj.moveBy(5, 5)

18 字符串操作类型

主要针对于一些字面量类型中的英文字母,进行一些大小写的转换后,构建出新的类型。

18.1 Uppercase<StringType>

将字符串类型转换为大写。

// type A = "HELLO"
type A = Uppercase<'hello'>

// type B = "HELLO" | "WORLD"
type B = Uppercase<'Hello' | 'World'>

// type C = "HELLO张三" | "WORLD李四"
type C = Uppercase<'Hello张三' | 'world李四'>

// type D = 10 | "HELLO"
type D = Uppercase<'hello' | 10>

18.2 Lowercase

将字符串类型转换为小写。

// type A = "hello"
type A = Lowercase<'HELLO'>

// type B = "hello" | "world"
type B = Lowercase<'Hello' | 'World'>

// type C = "world李四" | "hello张三"
type C = Lowercase<'Hello张三' | 'world李四'>

// type D = 10 | "hello"
type D = Lowercase<'HELLO' | 10>

18.3 Capitalize

将字符串类型的首字母转换为大写。

// type A = "Hello"
type A = Capitalize<'hello'>

// type B = "Hello" | "World"
type B = Capitalize<'hello' | 'world'>

// type C = "Hello张三" | "World李四"
type C = Capitalize<'hello张三' | 'world李四'>

// type D = "张三hello" | "李四world"
type D = Capitalize<'张三hello' | '李四world'>

// type E = 10 | "Hello"
type E = Capitalize<'hello' | 10>

18.4 Uncapitalize

将字符串类型的首字母转换为小写。

// type A = "hELLO"
type A = Uncapitalize<'HELLO'>

// type B = "hELLO" | "wORLD"
type B = Uncapitalize<'HELLO' | 'WORLD'>

// type C = "hELLO张三" | "wORLD李四"
type C = Uncapitalize<'HELLO张三' | 'WORLD李四'>

// type D = "张三Hello" | "李四World"
type D = Uncapitalize<'张三Hello' | '李四World'>

// type E = 10 | "hELLO"
type E = Uncapitalize<'HELLO' | 10>

摘录自:www.typescriptlang.org/docs/handbo…

原文链接:https://juejin.cn/post/7226387497566502972 作者:白哥学前端

(0)
上一篇 2023年4月27日 上午10:16
下一篇 2023年4月27日 上午10:26

相关推荐

发表回复

登录后才能评论