📜  TypeScript 中的泛型是什么?(1)

📅  最后修改于: 2023-12-03 14:48:04.890000             🧑  作者: Mango

TypeScript 中的泛型是什么?

在 TypeScript 中,泛型是一种允许我们创建可重用代码组件的工具。通过使用泛型,我们可以写出更加通用的代码,以适用于不同的类型和值。

泛型的基础

泛型可以用于函数、类和接口中。在使用泛型时,我们需要定义一个类型参数,它允许我们指定一个未知的类型或值。

函数中使用泛型

在函数中使用泛型时,我们可以把类型参数用作函数参数、函数返回值的类型或者在函数体中作为处理数据的类型。

function identity<T>(arg: T): T {
  return arg;
}

// 调用方式一:
let output1 = identity<string>("Hello World!");  // output1 的类型为 string
// 调用方式二:
let output2 = identity<number>(42);  // output2 的类型为 number

在上面的例子中,我们定义了一个叫做 identity 的函数,它使用了一个类型参数 T。当我们调用 identity 函数时,可以通过指定类型参数的值来传递相应的参数类型。在函数体内,我们使用泛型来保证输入和输出的类型相同。

类中使用泛型

在类中使用泛型时,我们可以把类型参数用作类的属性类型、方法的参数类型或者方法的返回值类型。

class DataStore<T> {
  private data: T[] = [];
  add(item: T) {
    this.data.push(item);
  }
  getAll() {
    return this.data;
  }
}

let ds1 = new DataStore<string>();
ds1.add("Hello");
ds1.add("World");
console.log(ds1.getAll());  // ["Hello", "World"]

let ds2 = new DataStore<number>();
ds2.add(1);
ds2.add(2);
console.log(ds2.getAll());  // [1, 2]

在上面的例子中,我们定义了一个叫做 DataStore 的类,它使用了一个类型参数 T。当我们实例化这个类时,可以通过指定类型参数的值来传递相应的属性和方法类型。在类的方法中,我们使用泛型来保证输入和输出的类型相同。

接口中使用泛型

在接口中使用泛型时,我们可以把类型参数用作接口的属性类型或者方法的参数类型和返回值类型。

interface Pair<T, U> {
  first: T;
  second: U;
}

let p1: Pair<number, string> = { first: 1, second: "Hello" };
let p2: Pair<string, boolean> = { first: "World", second: true };

在上面的例子中,我们定义了一个叫做 Pair 的接口,它使用了两个类型参数 TU。当我们定义一个变量时,可以通过指定类型参数的值来传递相应的属性类型。

泛型的进阶用法

泛型可以更加灵活地应用于我们的程序中,以便满足不同的需求和场景。

基于泛型的约束

在使用泛型时,我们可以对类型参数进行约束,以确保其符合特定的规定。我们可以使用关键字 extends 来进行类型约束。

interface Employee {
  name: string;
  age: number;
  salary: number;
}

function sortBySalary<T extends Employee>(items: T[]) {
  return items.sort((a, b) => a.salary - b.salary);
}

let employees: Employee[] = [
  { name: "Alice", age: 30, salary: 6000 },
  { name: "Bob", age: 25, salary: 5000 },
  { name: "Charlie", age: 35, salary: 8000 }
];

let sortedEmployees = sortBySalary(employees);
console.log(sortedEmployees);

在上面的例子中,我们定义了一个叫做 Employee 的接口,它定义了一些员工的属性。在函数 sortBySalary 中,我们使用了类型参数 T 并对其进行了约束,以确保其必须包含 Employee 接口中定义的属性。在函数体内,我们使用泛型来保证输入和输出的类型相同。

基于泛型的条件类型

在使用泛型时,我们还可以使用条件类型,以便根据类型参数的值来决定返回值的类型。我们可以使用 infer 关键字来指定返回值类型。

type isString<T> = T extends string ? true : false;

let a: isString<string> = true;
let b: isString<number> = false;
console.log(a, b);

在上面的例子中,我们定义了一个叫做 isString 的条件类型,它根据类型参数 T 的值来决定返回结果的类型。如果 Tstring 类型,则返回 true,否则返回 false

结论

泛型是一种强大的编程工具,在 TypeScript 中得到了广泛的应用。我们可以使用泛型来创建可重用的代码组件,以适用于不同的类型和值。通过一些进阶用法,我们可以使用泛型来完成更加复杂的任务,以便在我们的程序中得到更好的效果和性能。