返回

Typescript 骚操作大全——探索 TypeScript 开发秘籍

前端

排除原类型中特定 Key 或者特定 Value

在 TypeScript 中,我们可以使用Omit类型来排除原类型中特定的 Key。例如,我们有一个Person类型,包含nameagegender三个属性:

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

如果我们想创建一个新的类型PartialPerson,不包含age属性,我们可以使用Omit类型:

type PartialPerson = Omit<Person, "age">;

现在,PartialPerson类型只包含namegender两个属性:

interface PartialPerson {
  name: string;
  gender: string;
}

我们也可以使用Pick类型来选择原类型中的特定 Key。例如,我们想创建一个新的类型NameAndAgePerson,只包含nameage属性,我们可以使用Pick类型:

type NameAndAgePerson = Pick<Person, "name" | "age">;

现在,NameAndAgePerson类型只包含nameage两个属性:

interface NameAndAgePerson {
  name: string;
  age: number;
}

类型中某些属性只能“二选一”

在 TypeScript 中,我们可以使用Exclusive类型来实现类型中某些属性只能“二选一”。例如,我们有一个User类型,包含nameemail两个属性:

interface User {
  name: string;
  email: string;
}

如果我们想创建一个新的类型ExclusiveUser,要求nameemail两个属性只能存在一个,我们可以使用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,接受两个参数ab,并返回它们的和:

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,包含RedGreenBlue三个颜色:

enum PrimaryColor {
  Red,
  Green,
  Blue
}

我们想创建一个新的枚举类型SecondaryColor,包含OrangePurpleYellow三个颜色,并且继承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