工具类型
TypeScript
提供了一些工具类型,方便进行类型上的转换。这些工具类型是全局可见的。
# Partial
构造一个新类型,使类型 T
上的所有属性都变成可选的。
# 使用
interface Person {
name: string
age: number
}
type PersonOptional = Partial<Person>
// 相当于
type PersonOptional = {
name?: string
age?: number
}
# 实现
type Partial<T> = {
[K in keyof T]?: T[K]
}
# Required
设置类型的所有属性为必须项。和 Partial
是相反的。
# 使用
interface Person {
name?: string
age?: number
}
const Jack: Person = { name: 'Jack' }
const Lucy: Required<Person> = { name: 'Lucy' }
// Property 'age' is missing in type '{ name: string; }' but required in type 'Required<Person>'.(2741)
# 实现
type Required<T> = {
[K in keyof T]-?: T[K]
}
注意 -?
表示非可选,这里如果不加 -?
在遇到 T
的属性为可选时,就无法变成必选属性,这个就是指同态拷贝。
举个例子 🌰
interface T {
name: string
age?: number
}
// 实现一个不使用 `-?` 的 Required
type Required<T> = {
[K in keyof T]: T[K]
}
// Foo = { name: string, age?: number | undefined }
type Foo = Required<T>
// 添加 `-?`
type Required<T> = {
[K in keyof T]-?: T[K]
}
// Foo = { name: string, age: number }
type Foo = Required<T>
# Readonly
设置类型的所有属性为 readonly
。也就是不能再被赋值。
# 使用
interface Person {
name: string
age: number
}
const Lucy: Readonly<Person> = { name: 'Lucy', age: 18 }
Lucy.name = 'Jack'
// Cannot assign to 'name' because it is a read-only property.
# 实现
type Readonly<T> = {
readonly [K in keyof T]: T[K]
}
# Record<K, T>
构造一个对象类型, 它的 Keys
是 K
,它的 value
是 T
。
# 使用
type Point = {
lat: number
lng: number
}
type Line = Record<'start' | 'end', Point>
// 相当于
type Line = {
start: { lat: number; lng: number }
end: { lat: number; lng: number }
}
# 实现
type Record<K extends keyof any, T> = {
[P in K]: T
}
# Pick<T, K>
接口类型工具,从 T
类型中,选取 K
选项的属性,并组成新的类型。
# 使用
type House = {
lat: number
lng: number
address: string
color: string
}
type Point = Pick<House, 'lat' | 'lng'>
// 相当于
type Point = {
lat: number
lng: number
}
# 实现
type Pick<T, K extends keyof T> = {
[P in K]: T[P]
}
# Exclude<T, U>
联合类型工具,排除联合类型 T
中与 U
相等的类型,返回一个联合类型。
# 使用
interface Person {
name: string
age: number
}
type P = Exclude(keyof Person, 'age')
# 实现
type MyExclude<T, U> = T extends U ? never : T
# Omit<T, K>
从类型 T
中移除 K
中所有的属性。
# 使用
type House = {
lat: number
lng: number
address: string
color: string
}
// 移除 House 类型中的 color 和 address
type Point = Pick<House, 'color' | 'address'>
// 相当于
type Point = {
lat: number
lng: number
}
# 实现
type MyExclude<T, U> = T extends U ? never : T
type MyOmit<T, K extends keyof T> = {
[P in MyExclude<T, U>]: T[P]
}
# Extract<T, U>
联合类型工具,联合类型 T
和 U
的交集。
# 使用
type T = Extract<'name' | 'age' | 'sex', 'age' | 'height'>
// 相当于
type T = 'age'
# 实现
type MyExtract<T, U> = T extend U ? T : never
# NonNullable
排除联合类型中为 null
和 undefined
的类型
# 使用
type T = NonNullable<string | number | undefined | null>
// 等于
type T = string | number
# 实现
type MyNonNullable<T> = Exclude<T, null | undefined>
# Parameters
获取函数的参数类型,将每个参数类型放在一个元组中
# 使用
declare function f1(arg: { a: number; b: string })
type T0 = Parameters<() => string>
// T0 = []
type T1 = Parameters<(s: string) => void>
// T1 = [s: string]
type T2 = Parameters<<T>(arg: T) => T>
// T2 = [arg: unknown]
type T3 = Parameters<typeof f1>
// T3 = [arg: { a: number, b: string }]
# 实现
type MyParameters<T extends (...arg: any) => any> = T extends (
...args: infer P
) => any
? P
: never
# ConstructorParameters
获取类的构造函数的参数类型,存在一个元组中。
# 使用
class People {
constructor(public name: string, age?: number) {}
}
type Options = ConstructorParameters<typeof People>
// type Options = [name: string, age?: number | undefined]
# 实现
type MyConstructorParameters<T extends abstract new (...args: any) => any> =
T extends abstract new (...args: infer P) => any ? P : never
# ReturnType
获取函数的返回值类型
# 使用
const getPeopleInfo: (name: string) => {
name: string
age: number
weight: string
sex: string
} = (name: string) => {
return {
name,
age: 18,
weight: '79kg',
sex: 'male',
}
}
type T = ReturnType<typeof getPeopleInfo>
// T = { name: string; age: number; weight: string; sex: string; }
# 实现
type MyReturnType<T extends (...args: any) => any> = T extends (
...args: any
) => infer R
? R
: never
# TS Compiler 内部类型
# Uppercase
构造一个将字符串转大写的类型
type T = Uppercase<'abcde'>
// T = 'ABCDE'
# Lowercase
构造一个将字符串转小写的类型
type T = Lowercase<'ABCDe'>
// T = 'abcde'
# Capitalize
构造一个将字符串首字母转大写的类型
type T = Capitalize<'allen'>
// T = 'Allen'
# Uncapitalize
构造一个将字符串首字母转小写的类型
type T = Uncapitalize<'ALLEN'>
// T = aLLEN
# 参考
Last Updated: 4/8/2022, 2:53:25 PM