Typescript 骚操作大全——探索 TypeScript 开发秘籍
2023-12-08 19:47:30
排除原类型中特定 Key 或者特定 Value
在 TypeScript 中,我们可以使用Omit
类型来排除原类型中特定的 Key。例如,我们有一个Person
类型,包含name
、age
和gender
三个属性:
interface Person {
name: string;
age: number;
gender: string;
}
如果我们想创建一个新的类型PartialPerson
,不包含age
属性,我们可以使用Omit
类型:
type PartialPerson = Omit<Person, "age">;
现在,PartialPerson
类型只包含name
和gender
两个属性:
interface PartialPerson {
name: string;
gender: string;
}
我们也可以使用Pick
类型来选择原类型中的特定 Key。例如,我们想创建一个新的类型NameAndAgePerson
,只包含name
和age
属性,我们可以使用Pick
类型:
type NameAndAgePerson = Pick<Person, "name" | "age">;
现在,NameAndAgePerson
类型只包含name
和age
两个属性:
interface NameAndAgePerson {
name: string;
age: number;
}
类型中某些属性只能“二选一”
在 TypeScript 中,我们可以使用Exclusive
类型来实现类型中某些属性只能“二选一”。例如,我们有一个User
类型,包含name
和email
两个属性:
interface User {
name: string;
email: string;
}
如果我们想创建一个新的类型ExclusiveUser
,要求name
和email
两个属性只能存在一个,我们可以使用Exclusive
类型:
type ExclusiveUser = Exclusive<{
name: string;
email: string;
}>;
现在,ExclusiveUser
类型只能存在name
属性或者email
属性,但不能同时存在:
interface ExclusiveUser {
name: string;
}
// 报错:类型“ExclusiveUser”中不允许同时存在“name”和“email”属性。
interface ExclusiveUser {
email: string;
}
根据输入的参数类型决定其他参数类型
在 TypeScript 中,我们可以使用Infer
类型来根据输入的参数类型决定其他参数类型。例如,我们有一个函数add
,接受两个参数a
和b
,并返回它们的和:
function add(a: number, b: number): number {
return a + b;
}
如果我们想创建一个新的函数addOrConcat
,根据输入的参数类型决定是将它们相加还是将它们连接成字符串,我们可以使用Infer
类型:
function addOrConcat<T>(a: T, b: T): T extends number ? number : string {
if (typeof a === "number" && typeof b === "number") {
return a + b;
} else {
return a.toString() + b.toString();
}
}
现在,addOrConcat
函数可以根据输入的参数类型决定是将它们相加还是将它们连接成字符串:
addOrConcat(1, 2); // 返回 3
addOrConcat("Hello", "World"); // 返回 "HelloWorld"
真正的枚举
在 TypeScript 中,枚举类型只是一种语法糖,实际上还是一种数字联合类型。例如,我们有一个枚举类型Color
:
enum Color {
Red,
Green,
Blue
}
实际上,Color
类型等价于以下数字联合类型:
type Color = 0 | 1 | 2;
如果我们想创建一个真正的枚举类型,我们可以使用const
const Color = {
Red: "Red",
Green: "Green",
Blue: "Blue"
};
现在,Color
类型是一个真正的枚举类型,它不能被赋值为数字:
// 报错:不能将类型“number”赋值给类型“{ Red: string; Green: string; Blue: string; }”。
const color: Color = 1;
继承一个枚举(枚举的继承)
在 TypeScript 中,枚举类型可以继承另一个枚举类型。例如,我们有一个枚举类型PrimaryColor
,包含Red
、Green
和Blue
三个颜色:
enum PrimaryColor {
Red,
Green,
Blue
}
我们想创建一个新的枚举类型SecondaryColor
,包含Orange
、Purple
和Yellow
三个颜色,并且继承PrimaryColor
枚举类型:
enum SecondaryColor extends PrimaryColor {
Orange,
Purple,
Yellow
}
现在,SecondaryColor
枚举类型继承了PrimaryColor
枚举类型的所有成员,并且还添加了三个新的成员:
console.log(SecondaryColor.Red); // 0
console.log(SecondaryColor.Green); // 1
console.log(SecondaryColor.Blue); // 2
console.log(SecondaryColor.Orange); // 3
console.log(SecondaryColor.Purple); // 4
console.log(SecondaryColor.Yellow); // 5