Typescript 之类型工具:实用又万能!
2023-09-30 07:49:19
前言
Typescript 中默认内置了很多工具泛型,通过使用这些工具,可以使得我们定义类型更加灵活,高效。本文将会介绍常用泛型工具的使用技巧,以及对其实现原理进行相应的解析。
Partial
介绍
Partial<T>
用于将类型 T 中所有的属性都变为可选的。当我们不想让类型 T 中的所有属性都为必填时,可以使用 Partial 来放松对这些属性的要求。
使用示例
interface Person {
name: string;
age: number;
gender: string;
}
// 定义一个可部分修改的 Person 类型
type PartialPerson = Partial<Person>;
// 使用 PartialPerson 类型来定义一个对象
const person: PartialPerson = {
name: 'John',
// age 和 gender 属性可以不指定
};
实现原理
Partial<T>
的实现原理是使用一个联合类型。对于类型 T 中的每个属性 key,Partial<T>
会创建一个新的键值对 [key: T[key]],其中 T[key] 是类型 T 中属性 key 的类型。然后,Partial<T>
将这些新的键值对与 T 中的原有属性一起组合成一个新的联合类型。
type Partial<T> = {
[key in keyof T]?: T[key];
};
Required
介绍
Required<T>
用于将类型 T 中所有的属性都变为必填的。当我们想让类型 T 中的所有属性都为必填时,可以使用 Required 来强制要求这些属性必须要有值。
使用示例
interface Person {
name?: string;
age?: number;
gender?: string;
}
// 定义一个必填的 Person 类型
type RequiredPerson = Required<Person>;
// 使用 RequiredPerson 类型来定义一个对象
const person: RequiredPerson = {
name: 'John',
age: 30,
gender: 'male',
};
实现原理
Required<T>
的实现原理是使用一个交叉类型。对于类型 T 中的每个属性 key,Required<T>
会创建一个新的键值对 [key: T[key]],其中 T[key] 是类型 T 中属性 key 的类型。然后,Required<T>
将这些新的键值对与 T 中的原有属性一起组合成一个新的交叉类型。
type Required<T> = {
[key in keyof T]-?: T[key];
};
Readonly
介绍
Readonly<T>
用于将类型 T 中所有的属性都变为只读的。当我们不想让类型 T 中的任何属性可以被修改时,可以使用 Readonly 来保护这些属性。
使用示例
interface Person {
name: string;
age: number;
gender: string;
}
// 定义一个只读的 Person 类型
type ReadonlyPerson = Readonly<Person>;
// 使用 ReadonlyPerson 类型来定义一个对象
const person: ReadonlyPerson = {
name: 'John',
age: 30,
gender: 'male',
};
// 尝试修改 person 对象的属性会报错
person.name = 'Jane'; // error: Cannot assign to 'name' because it is a read-only property.
实现原理
Readonly<T>
的实现原理是使用一个联合类型。对于类型 T 中的每个属性 key,Readonly<T>
会创建一个新的键值对 [key: readonly T[key]],其中 T[key] 是类型 T 中属性 key 的类型。然后,Readonly<T>
将这些新的键值对与 T 中的原有属性一起组合成一个新的联合类型。
type Readonly<T> = {
readonly [key in keyof T]: T[key];
};
Pick
介绍
Pick<T, K>
用于从类型 T 中挑选出指定的属性 K,并组成一个新的类型。当我们只想使用类型 T 中的某些属性时,可以使用 Pick 来提取这些属性。
使用示例
interface Person {
name: string;
age: number;
gender: string;
address: string;
}
// 从 Person 类型中挑选出 name 和 age 属性
type NameAndAge = Pick<Person, 'name' | 'age'>;
// 使用 NameAndAge 类型来定义一个对象
const person: NameAndAge = {
name: 'John',
age: 30,
};
实现原理
Pick<T, K>
的实现原理是使用一个交叉类型。对于类型 T 中的每个属性 key,如果 key 存在于 K 中,则 Pick<T, K>
会创建一个新的键值对 [key: T[key]],其中 T[key] 是类型 T 中属性 key 的类型。然后,Pick<T, K>
将这些新的键值对与 T 中的原有属性一起组合成一个新的交叉类型。
type Pick<T, K extends keyof T> = {
[key in K]: T[key];
};
Omit
介绍
Omit<T, K>
用于从类型 T 中排除指定的属性 K,并组成一个新的类型。当我们不想使用类型 T 中的某些属性时,可以使用 Omit 来去除这些属性。
使用示例
interface Person {
name: string;
age: number;
gender: string;
address: string;
}
// 从 Person 类型中排除 address 属性
type PersonWithoutAddress = Omit<Person, 'address'>;
// 使用 PersonWithoutAddress 类型来定义一个对象
const person: PersonWithoutAddress = {
name: 'John',
age: 30,
gender: 'male',
};
实现原理
Omit<T, K>
的实现原理是使用一个交叉类型。对于类型 T 中的每个属性 key,如果 key 不存在于 K 中,则 Omit<T, K>
会创建一个新的键值对 [key: T[key]],其中 T[key] 是类型 T 中属性 key 的类型。然后,Omit<T, K>
将这些新的键值对与 T 中的原有属性一起组合成一个新的交叉类型。
type Omit<T, K extends keyof T> = {
[key in Exclude<keyof T, K>]: T[key];
};
Conclusion
以上便是 Typescript 中常用工具类型的一些介绍和使用示例,希望对您有所帮助。这些工具类型可以帮助我们定义更加灵活和高效的类型,从而使我们的代码更加健壮和易于维护。