返回

TypeScript中的泛型限制:深入理解extends约束的奥秘

前端

在TypeScript中,extends约束允许我们指定泛型类型T必须是另一个类型S的子类型,或者说T必须继承S。这可以确保在使用泛型类型时,传入的参数或属性类型与我们预期的类型兼容,从而避免类型错误。

以下代码演示了extends约束的使用:

interface Shape {
  draw(): void;
}

interface Circle extends Shape {
  radius: number;
}

function drawShape(shape: Shape): void {
  shape.draw();
}

const circle: Circle = {
  radius: 5,
  draw() {
    console.log("Drawing a circle with radius", this.radius);
  },
};

drawShape(circle);

在这个例子中,我们定义了一个Shape接口和一个Circle接口,Circle继承了Shape。我们在drawShape函数中指定了参数类型为Shape,这意味着该函数可以接受任何实现了Shape接口的对象。当我们传入一个Circle类型的circle对象时,TypeScript会检查Circle是否继承了Shape,由于Circle确实继承了Shape,因此可以成功调用drawShape函数。

extends约束还可以用于约束泛型类型的属性类型。例如,我们可以这样定义一个函数,要求其参数具有一个名为name的属性,并且该属性的类型必须是字符串:

function getUserName<T extends { name: string }>(person: T): string {
  return person.name;
}

const user = {
  name: "John Doe",
};

const userName = getUserName(user);

console.log(userName); // "John Doe"

在这个例子中,我们定义了getUserName函数,其参数类型约束为T extends { name: string }。这表示T必须是一个具有name属性的类型,并且name属性的类型必须是字符串。当我们传入一个具有name属性且类型为字符串的对象user时,TypeScript会检查user是否符合T的约束条件,由于user确实符合约束条件,因此可以成功调用getUserName函数。

extends约束是TypeScript中一种非常有用的约束,它可以帮助我们确保泛型类型的兼容性,并避免类型错误。通过理解和掌握extends约束,我们可以编写出更加类型安全和健壮的TypeScript代码。