TypeScript 如何向泛型类型添加约束

TypeScript 如何向泛型类型添加约束

TypeScript是一个开源的编程语言,提供了对JavaScript的类型注解。TypeScript具有泛型类型,使开发人员能够编写可以适用于不同数据类型的代码。泛型提供了代码的灵活性和可重用性。然而,在某些情况下,有必要向泛型类型添加约束,以限制可以与其一起使用的类型。

在本文中,我们将解释在TypeScript中如何向泛型类型添加约束,并讨论一些示例。

什么是泛型类型

在我们深入了解约束之前,让我们先了解一下泛型类型是什么。TypeScript中的泛型类型允许开发人员定义可以与各种数据类型一起使用的类型。这意味着函数、类或接口可以接收任何类型的数据,使代码更加灵活和可重用。

例如,让我们考虑一个简单的函数,它接受两个参数并返回这两个参数的和。

function add(a, b) {
   return a + b;
}

这个函数对于数字来说工作得很好,但是如果我们想要添加两个字符串或者两个数组怎么办?我们就得为每种数据类型写不同的函数,这样效率不高。相反,我们可以使用通用类型来创建一个可以适用于任何数据类型的函数。

function add<T>(a: T, b: T): T {
   return a + b;
}

在这里,函数 add 具有通用类型 T ,可以代表任何数据类型。该函数接受两个类型为 T 的参数,并返回一个类型为 T 的值。

为通用类型添加约束

虽然通用类型提供了灵活性,但在某些情况下,我们可能希望添加约束来限制可以与其一起使用的类型。添加约束可以提高代码质量,并帮助在编译时而不是运行时捕捉错误。

通过使用关键字 extends 后跟要约束通用类型的类型或接口来添加约束。

语法

function functionName<T extends ConstraintType>(arg1: Arg1Type, arg2: Arg2Type, ...): ReturnType {
   // function body
}
  • functionName − 使用具有约束条件的通用类型的函数的名称

  • <T extends ConstraintType> − 定义通用类型T并使用extends关键字指定约束条件。ConstraintType可以是TypeScript中的任何有效类型,包括接口、类和原始类型。

  • (arg1: Arg1Type, arg2: Arg2Type, ...) − 函数传递的参数及其类型。

  • : ReturnType − 函数的返回类型。

  • function body − 函数的实现,使用由指定的ConstraintType约束的通用类型T。

需要注意的是,约束条件只能应用于函数中的一个通用类型。如果使用了多个通用类型,则每个通用类型必须有自己的约束条件。此外,可以通过使用交叉类型在单个通用类型上有多个约束条件。

示例

示例1:对数组施加约束

function getLength<T extends Array<any>>(arr: T): number {
   return arr.length;
}

在这个例子中,我们为通用类型 T 添加了一个约束使用 extends 关键字。约束指定类型 T 必须扩展 Array <any>>类型。这意味着函数 getLength 只能用于数组。

我们可以举个例子来验证一下。

function getLength<T extends Array<any>>(arr: T): number {
   return arr.length;
}
const arr = [6, 7];
console.log(`The length of the array is: ${getLength(arr)}`);

编译后,将生成以下 JavaScript 代码 –

function getLength(arr) {
   return arr.length;
}
var arr = [6, 7];
console.log("The length of the array is: ".concat(getLength(arr)));

输出

The length of the array is: 2

示例2:对象的约束

在这个例子中,我们给两个泛型类型 TK 添加了约束,使用了 extends 关键字。约束指定类型 T 必须扩展Person接口,类型 K 必须扩展类型 T 的键。这意味着函数 getProperty 只能用于 Person 类型的对象和存在于该接口中的键。

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

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

const person: Person = {
   name: "John",
   age: 21,
};

console.log(`The name of the person is: ${getProperty(person, "name")}`);

编译时,它将生成以下JavaScript代码−

function getProperty(obj, key) {
   return obj[key];
}
var person = {
   name: "John",
   age: 21
};
console.log("The name of the person is: ".concat(getProperty(person, "name")));

输出结果

The name of the person is: John

示例3:类的约束

在这个例子中,我们使用了 extends 关键字来给泛型类型 T 添加了一个约束。这个约束指定了类型 T 必须扩展自 Animal 类。这意味着 Zoo 类只能与动物对象一起使用。

Class Animl {
}
class Animal {
   name: string;
   constructor(name: string) {
      this.name = name;
   }
}
class Zoo<T extends Animal> {
   animals: T[];
   constructor(animals: T[]) {
      this.animals = animals;
   }
}
const lion = new Animal('Lion');
const tiger = new Animal('Tiger');
const zoo = new Zoo<Animal>([lion, tiger]);
const zoo1 = new Zoo<Animl>([lion, tiger])  // gives error

输出

编译时,它会生成以下错误 –

Type 'Animl' does not satisfy the constraint 'Animal'.
Property 'name' is missing in type 'Animl' but required in type 'Animal'.

TypeScript 如何向泛型类型添加约束

示例4:对函数的约束

在这个例子中,我们对泛型类型 T 添加了一个约束,使用了 extends 关键字。约束规定了类型 T 必须是可以与 Array 类型一起使用的任何类型。这意味着函数 filter 只能与数组一起使用,并且第二个参数 predicate 必须是一个接受 T 类型项并返回布尔值的函数。

function filter<T>(array: T[], predicate: (item: T) => boolean): T[] {
   return array.filter(predicate);
}
const numbers = [1, 2, 3, 4, 5];
const evenNumbers = filter(numbers, (item) => item % 2 === 0);
console.log(`The numbers afer applying filter are: ${evenNumbers}`);

编译后,将生成以下JavaScript代码 –

function filter(array, predicate) {
   return array.filter(predicate);
}
var numbers = [1, 2, 3, 4, 5];
var evenNumbers = filter(numbers, function (item) { return item % 2 === 0; });
console.log("The numbers afer applying filter are: ".concat(evenNumbers));

输出

The numbers afer applying filter are: 2,4

结论

总之,在TypeScript中给泛型类型添加约束是一个有力的功能,可以帮助开发人员编写更健壮和灵活的代码。可以通过添加约束来限制可以与泛型类型一起使用的类型,从而提高代码质量并在编译时捕获错误。通过使用extends关键字后跟我们想约束泛型类型的类型或接口,开发人员可以创建更可靠和可维护的代码。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程