TypeScript 泛型约束

摘要:在本教程中,您将学习 TypeScript 中的泛型约束。

TypeScript 中泛型约束简介

请考虑以下示例

function merge<U, V>(obj1: U, obj2: V) {
    return {
        ...obj1,
        ...obj2
    };
}Code language: TypeScript (typescript)

merge() 是一个泛型函数,用于合并两个对象。例如

let person = merge(
    { name: 'John' },
    { age: 25 }
);

console.log(result);Code language: TypeScript (typescript)

输出

{ name: 'John', age: 25 }Code language: TypeScript (typescript)

它工作得很好。

merge() 函数期望两个对象。但是,它不会阻止您传递非对象,如下所示

let person = merge(
    { name: 'John' },
    25
);

console.log(person);Code language: TypeScript (typescript)

输出

{ name: 'John' }Code language: TypeScript (typescript)

TypeScript 不会发出任何错误。

除了处理所有类型之外,您可能还想向 merge() 函数添加约束,使其仅与对象一起使用。

为此,您需要将要求列为对 UV 类型可以是什么的约束。

为了表示约束,您使用 extends 关键字。例如

function merge<U extends object, V extends object>(obj1: U, obj2: V) {
    return {
        ...obj1,
        ...obj2
    };
}
Code language: TypeScript (typescript)

由于 merge() 函数现在受到约束,因此它将不再与所有类型一起使用。相反,它仅与 object 类型一起使用。

以下将导致错误

let person = merge(
    { name: 'John' },
    25
);Code language: TypeScript (typescript)

错误

Argument of type '25' is not assignable to parameter of type 'object'.Code language: TypeScript (typescript)

在泛型约束中使用类型参数

TypeScript 允许您声明受另一个类型参数约束的类型参数。

以下 prop() 函数接受一个对象和一个属性名称。它返回属性的值。

function prop<T, K>(obj: T, key: K) {
    return obj[key];
}Code language: TypeScript (typescript)

编译器会发出以下错误

Type 'K' cannot be used to index type 'T'.Code language: TypeScript (typescript)

要解决此错误,您需要向 K 添加约束,以确保它是 T 的键,如下所示

function prop<T, K extends keyof T>(obj: T, key: K) {
    return obj[key];
}Code language: TypeScript (typescript)

如果将 obj 上存在的属性名称传递给 prop 函数,编译器将不会报错。例如

let str = prop({ name: 'John' }, 'name');
console.log(str);Code language: TypeScript (typescript)

输出

JohnCode language: TypeScript (typescript)

但是,如果您传递第一个参数上不存在的键,编译器将发出错误

let str = prop({ name: 'John' }, 'age');Code language: TypeScript (typescript)

错误

Argument of type '"age"' is not assignable to parameter of type '"name"'.Code language: TypeScript (typescript)

总结

  • 使用 extends 关键字将类型参数约束为特定类型。
  • 使用 extends keyof 来约束作为另一个对象属性的类型。
本教程是否有帮助?