Skip to content

工具类型

Partial

Partial<T> 的作用就是将某个类型里的属性全部变为可选项 ?

定义:

typescript
// node_modules/typescript/lib/lib.es5.d.ts

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

在以上代码中,首先通过 keyof T 拿到 T 的所有属性名,然后使用 in 进行遍历,将值赋给 P,最后通过 T[P] 取得相应的属性值。中间的 ?,用于将所有属性变为可选。

示例:

typescript
interface Todo {
  title: string
  description: string
}

function updateTodo(todo: Todo, fieldsToUpdate: Partial<Todo>) {
  return { ...todo, ...fieldsToUpdate }
}

const todo1 = {
  title: 'organize desk',
  description: 'clear clutter'
}

const todo2 = updateTodo(todo1, {
  description: 'throw out trash'
})

Required

Required 的作用刚好跟 Partial 相反,Partial 是将所有属性改成可选项,Required 则是将所有类型改成必选项。

定义:

typescript
// node_modules/typescript/lib/lib.es5.d.ts

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

以上代码中,-? 的作用就是移除可选项 ?

与之对应的还有个 +? , 这个含义自然与 -? 之前相反, 它是用来把属性变成可选项的,+ 可省略,见 Partial

示例:

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

const obj: Props = { a: 5 } // OK
const obj2: Required<Props> = { a: 5 } // Error: property 'b' missing

Readonly

Readonly<T> 的作用是将某个类型所有属性变为只读属性,也就意味着这些属性不能被重新赋值。

定义:

typescript
// node_modules/typescript/lib/lib.es5.d.ts

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

给子属性添加 readonly 的标识,如果将上面的 readonly 改成 -readonly, 就是移除子属性的 readonly 标识。

示例:

typescript
interface Todo {
  title: string
}

const todo: Readonly<Todo> = {
  title: 'Delete inactive users'
}

todo.title = 'Hello' // Error: cannot reassign a readonly property

Readonly<T> 对于表示在运行时将赋值失败的表达式很有用(比如,当尝试重新赋值冻结对象的属性时)。

text
function freeze<T>(obj: T): Readonly<T>;

Record

Record 的作用是将 K 中所有的属性的值转化为 T 类型。

定义:

typescript
// node_modules/typescript/lib/lib.es5.d.ts

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

示例:

Record 通常用于描述一个对keyvalue 类型都有明确约束的对象,比方说,我们要求一个对象的 key 只能为 "home" | "about" | "contact" 其中一种,value 只能为 PageInfo 类型, 那么我们进行如下定义:

typescript
interface PageInfo {
  title: string
}

type Page = 'home' | 'about' | 'contact'

const x: Record<Page, PageInfo> = {
  about: { title: 'about' },
  contact: { title: 'contact' },
  home: { title: 'home' }
}

Pick

Pick 的作用是将某个类型中的某些子属性挑出来,变成包含这个类型部分属性的子类型。

定义:

typescript
// node_modules/typescript/lib/lib.es5.d.ts

/**
 * 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]
}

示例:

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

type TodoPreview = Pick<Todo, 'title' | 'completed'>

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

Omit

Omit 的作用刚好跟 Pick 相反,Pick 是从一个类型中挑选出某些类型,而 Omit 则是从一个类型中剔除掉某些类型。

定义:

typescript
// node_modules/typescript/lib/lib.es5.d.ts

/**
 * 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>>

示例:

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

type TodoPreview = Omit<Todo, 'description'>

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

Exclude

Exclude<T, U> 的作用是剔除掉 T 包含在 U 中的元素,换种更加贴近语义的说法就是从 T 中剔除出 U

定义:

typescript
// node_modules/typescript/lib/lib.es5.d.ts

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

以上语句的意思就是 如果 T 能赋值给 U 类型的话,那么就会返回 never 类型,否则返回 T,最终结果是将 T 中的某些属于 U 的类型移除掉。

示例:

typescript
type T0 = Exclude<'a' | 'b' | 'c', 'a'> // "b" | "c"
type T1 = Exclude<'a' | 'b' | 'c', 'a' | 'b'> // "c"
type T2 = Exclude<string | number | (() => void), Function> // string | number

Extract

Extract<T, U> 的作用是提取出 T 包含在 U 中的元素,换种更加贴近语义的说法就是从 T 中提取出 U

定义:

typescript
// node_modules/typescript/lib/lib.es5.d.ts

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

以上语句的意思就是 如果 T 能赋值给 U 类型的话,那么就会返回 T 类型,否则返回 never,最终结果是将 TU 中共有的属性提取出来。

示例:

typescript
type T01 = Extract<'a' | 'b' | 'c' | 'd', 'a' | 'c' | 'f'> // -> 'a' | 'c'

可以看到 T'a' | 'b' | 'c' | 'd' ,然后 U'a' | 'c' | 'f' ,返回的新类型就可以将 TU 中共有的属性提取出来,也就是 'a' | 'c' 了。

NonNullable

NonNullable 的作用是用来过滤类型中的 nullundefined 类型。

定义:

typescript
// node_modules/typescript/lib/lib.es5.d.ts

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

示例:

typescript
type T0 = NonNullable<string | number | undefined> // string | number
type T1 = NonNullable<string[] | null | undefined> // string[]

ReturnType

ReturnType 的作用是用于获取函数的返回类型。

定义:

typescript
// node_modules/typescript/lib/lib.es5.d.ts

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

示例:

typescript
type T0 = ReturnType<() => string> // string
type T1 = ReturnType<(s: string) => void> // void
type T2 = ReturnType<<T>() => T> // {}
type T3 = ReturnType<<T extends U, U extends number[]>() => T> // number[]
type T4 = ReturnType<any> // any
type T5 = ReturnType<never> // any
type T6 = ReturnType<string> // Error
type T7 = ReturnType<Function> // Error

Parameters

Parameters 的作用是用于获得函数的参数类型组成的元组类型。

定义:

typescript
// node_modules/typescript/lib/lib.es5.d.ts

/**
 * 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

示例:

typescript
type A = Parameters<() => void> // []
type B = Parameters<typeof Array.isArray> // [any]
type C = Parameters<typeof parseInt> // [string, (number | undefined)?]
type D = Parameters<typeof Math.max> // number[]

InstanceType

InstanceType 的作用是获取构造函数类型的实例类型。

定义:

typescript
// node_modules/typescript/lib/lib.es5.d.ts

/**
 * 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
class C {
  x = 0
  y = 0
}

type T0 = InstanceType<typeof C> // C
type T1 = InstanceType<any> // any
type T2 = InstanceType<never> // any
type T3 = InstanceType<string> // Error
type T4 = InstanceType<Function> // Error

ThisType

ThisType<T> 的作用是用于指定上下文对象的类型。

定义:

typescript
// node_modules/typescript/lib/lib.es5.d.ts

/**
 * Marker for contextual 'this' type
 */
interface ThisType<T> {}

注意:使用 ThisType<T> 时,必须确保 --noImplicitThis 标志设置为 true。

示例:

text
interface Person {
    name: string;
    age: number;
}

const obj: ThisType<Person> = {
  dosth() {
    this.name // string
  }
}

ConstructorParameters

ConstructorParameters<T> 的作用是提取构造函数类型的所有参数类型。它会生成具有所有参数类型的元组类型(如果 T 不是函数,则返回的是 never 类型)。

定义:

typescript
// node_modules/typescript/lib/lib.es5.d.ts

/**
 * 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

示例:

typescript
type A = ConstructorParameters<ErrorConstructor> // [(string | undefined)?]
type B = ConstructorParameters<FunctionConstructor> // string[]
type C = ConstructorParameters<RegExpConstructor> // [string, (string |

如有转载或 CV 的请标注本站原文地址