跳到主要内容

TypeScript 泛型约束

泛型是TypeScript中非常强大的特性,它允许我们编写灵活且可重用的代码。然而,有时我们希望泛型参数不仅仅是任意类型,而是具有某些特定属性或行为的类型。这时,泛型约束就派上用场了。

什么是泛型约束?

泛型约束允许我们为泛型参数添加限制条件,确保它满足某些特定的要求。通过使用泛型约束,我们可以确保泛型参数具有某些属性或方法,从而在编译时捕获潜在的错误。

基本语法

泛型约束的基本语法如下:

typescript
function example<T extends ConstraintType>(arg: T): void {
// 函数体
}

在这里,T 是泛型参数,extends ConstraintType 表示 T 必须满足 ConstraintType 的约束条件。

示例:使用泛型约束

假设我们有一个函数,它接受一个对象并返回该对象的 length 属性。我们希望确保传入的对象确实具有 length 属性。

typescript
function getLength<T extends { length: number }>(obj: T): number {
return obj.length;
}

在这个例子中,T 必须是一个具有 length 属性的对象,且 length 属性的类型必须是 number

输入和输出

typescript
const str = "Hello, TypeScript!";
const arr = [1, 2, 3, 4, 5];

console.log(getLength(str)); // 输出: 18
console.log(getLength(arr)); // 输出: 5

如果我们尝试传入一个没有 length 属性的对象,TypeScript 会在编译时报错:

typescript
const num = 42;
console.log(getLength(num)); // 编译错误: 类型 'number' 的参数不能赋给类型 '{ length: number; }' 的参数

实际应用场景

场景1:确保对象具有特定属性

假设我们正在开发一个函数,它需要处理具有 name 属性的对象。我们可以使用泛型约束来确保传入的对象具有 name 属性。

typescript
interface Named {
name: string;
}

function greet<T extends Named>(obj: T): string {
return `Hello, ${obj.name}!`;
}

const person = { name: "Alice", age: 30 };
console.log(greet(person)); // 输出: Hello, Alice!

场景2:限制泛型参数为特定类型

有时我们希望泛型参数只能是某些特定类型。例如,我们可能希望一个函数只能接受 stringnumber 类型的参数。

typescript
function logValue<T extends string | number>(value: T): void {
console.log(`Value: ${value}`);
}

logValue("TypeScript"); // 输出: Value: TypeScript
logValue(42); // 输出: Value: 42
logValue(true); // 编译错误: 类型 'boolean' 的参数不能赋给类型 'string | number' 的参数

总结

泛型约束是TypeScript中一个非常有用的特性,它允许我们在编写泛型代码时对类型参数进行限制,从而确保代码的类型安全性和灵活性。通过使用泛型约束,我们可以避免潜在的错误,并编写出更加健壮的代码。

附加资源

练习

  1. 编写一个函数 getProperty,它接受一个对象和一个属性名,并返回该属性的值。使用泛型约束确保属性名是对象的一个键。

  2. 创建一个泛型函数 mergeObjects,它接受两个对象并返回它们的合并结果。使用泛型约束确保两个对象都是 object 类型。

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

function mergeObjects<T extends object, U extends object>(obj1: T, obj2: U): T & U {
return { ...obj1, ...obj2 };
}

通过这些练习,你将更好地理解泛型约束的实际应用。