【TypeScript】Utility Types 高级实用工具类型

Awaited<Type>

// 用来描述promise中then的返回值类型
type T = Awaited<boolean | Promise<number>>
// 等价于
type T = number | boolean

Partial<Type>

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

interface Todo {
  title: string
  description: string
}

// 必要属性类型都转为可选属性类型
const p1: Partial<Todo> = {
  title: 'organize desk',
  description: 'clear clutter'
} // OK

const p2: Partial<Todo> = {
  title: 'organize desk'
} // OK

Required<Type>

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

interface Props {
  a?: number
  b?: string
}

// 所有属性类型都转为必要属性类型
const p1: Required<Props> = { a: 5, b: '123' } // OK
const p2: Required<Props> = { a: 5 } // Error

Readonly<Type>

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

interface Todo {
  title: string
}
// 所有属性类型都转为只读类型,不能再次修改
const todo: Readonly<Todo> = {
  title: 'Delete inactive users'
}

todo.title = 'Hello' // Error

// 使用场景:(冻结对象)
function freeze<Type>(obj: Type): Readonly<Type>

Record<K,T>

// 作用:将K中的每个属性([P in K]),都转为T类型
type Record<K extends keyof any, T> = {
  [P in K]: T
}

interface CatInfo {
  age: number
  breed: string
}

type CatName = 'miffy' | 'boris' | 'mordred'

const cats: Record<CatName, CatInfo> = {
  miffy: { age: 10, breed: 'Persian' },
  boris: { age: 5, breed: 'Maine Coon' },
  mordred: { age: 16, breed: 'British Shorthair' }
}

Pick<Type, Keys>

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

interface Todo {
  title: string
  description: string
  completed: boolean
}

// 挑选部分属性类型,作为新的类型
type TodoPreview = Pick<Todo, 'title' | 'completed'>

const todo: TodoPreview = {
  title: 'Clean room',
  completed: false
}

Omit<Type, Keys>

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

interface Todo {
  title: string
  description: string
  completed: boolean
  createdAt: number
}
// 略掉部分属性类型,作为新的类型
type TodoInfo = Omit<Todo, 'completed' | 'createdAt'>

const todoInfo: TodoInfo = {
  title: 'Pick up kids',
  description: 'Kindergarten closes at 5pm'
}

Exclude<UnionType, ExcludedMembers>

// 从联合类型中剔除一些类型,作为新的类型
type Exclude<T, U> = T extends U ? never : T

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

type Shape =
  | { kind: 'circle'; radius: number }
  | { kind: 'square'; x: number }
  | { kind: 'triangle'; x: number; y: number }

type T3 = Exclude<Shape, { kind: 'circle' }>
// type T3 = { kind: 'square'; x: number } | { kind: 'triangle'; x: number; y: number }

Extract<Type, Union>

// 从联合类型中抽取一些类型,作为新的类型
type Extract<T, U> = T extends U ? T : never

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

NonNullable<Type>

// 从联合类型中剔除null 和 undefined,作为新的类型
type NonNullable<T> = T extends null | undefined ? never : T

type T0 = NonNullable<string | number | undefined>
type T0 = string | number

Parameters<Type>

// 获取函数参数的类型,组成一个元组类型的新类型
type Parameters<T extends Function> = ((...args: infer U) => any) | (new (...args: infer U) => any) ? U : any[];

declare function f1(arg: { a: number; b: string }): void
type T3 = Parameters<typeof f1>
// type T3 = [arg: {
//     a: number;
//     b: string;
// }]

type T1 = Parameters<(s: string, n: number) => void>
// type T1 = [s: string, n: nubmer]

ConstructorParameters<Type>

// 提取构造函数的参数类型,组成一个元组类型的新类型
type ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never

class C {
  constructor(a: number, b: string) {}
}
type T3 = ConstructorParameters<typeof C>
// type T3 = [a: number, b: string]

ReturnType<Type>

// 提取函数的返回值的参数类型,组成一个新类型
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any

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

declare function f1(): { a: number; b: string }
type T4 = ReturnType<typeof f1>
// type T4 = {
//   a: number
//   b: string
// }

InstanceType<Type>

// 提取实例对象的类型(对象实例化之前的class类)
type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any

class C {
  x = 0
  y = 0
}

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

ThisParameterType<Type>

// 提取函数中 this 参数的类型,没有this 类型为 unknown
type ThisParameterType<T> = T extends (this: infer U, ...args: any[]) => any ? U : unknown

function toHex(this: Number) {
  return this.toString(16)
}

function numberToString(n: ThisParameterType<typeof toHex>) {
  return toHex.apply(n)
}

OmitThisParameter<Type>

// 没有this参数,返回传入函数的类型
// 有 this 参数,剔除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)
}

function numberToString(n: ThisParameterType<typeof toHex>) {
  return toHex.apply(n)
}

ThisType<Type>

// 充当对象执行上下文 this 的标记, 不返回类型。
type ObjectDescriptor<D, M> = {
  data?: D
  methods?: M & ThisType<D & M> // Type of 'this' in methods is D & M
}

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

let obj = makeObject({
  data: { x: 0, y: 0 },
  methods: {
    moveBy(dx: number, dy: number) {
      this.x += dx // Strongly typed this
      this.y += dy // Strongly typed this
    }
  }
})

obj.x = 10
obj.y = 20
obj.moveBy(5, 5)
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值