TypeScript 类、泛型的使用实践记录 | 青训营

64 阅读3分钟

TypeScript中的泛型是一种强大的工具,可以增加代码的灵活性和安全性。泛型允许我们编写可重用的代码,以处理多种数据类型,而不失去类型检查的好处。以下是关于TypeScript中类和泛型的使用实践记录,包括示例代码和常见场景。

1. 泛型基础:

泛型允许我们将类型作为参数传递给函数或类,从而在不同地方使用相同的代码,但可以应对不同的数据类型。以下是一个简单的泛型函数示例:

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

const result1: number = identity(42);      // 返回数字
const result2: string = identity("Hello");  // 返回字符串

在上述示例中,identity函数是一个泛型函数,它可以接受不同类型的参数并返回相同类型的结果。

2. 类中的泛型:

泛型不仅可以用于函数,还可以用于类。例如,您可以创建一个泛型类来表示一对值:

typescript
class Pair<T, U> {
    constructor(public first: T, public second: U) {}
}

const pair1 = new Pair(42, "Hello");
const pair2 = new Pair(true, [1, 2, 3]);

在上述示例中,Pair类是一个泛型类,可以用于存储不同类型的值。

3. 泛型类型约束:

有时,我们希望泛型参数只能是某种特定类型。这可以通过类型约束来实现。例如,我们可以创建一个泛型函数,要求输入的参数具有某种方法:

typescript
interface HasLength {
    length: number;
}

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

const length1 = getLength("Hello");    // 5
const length2 = getLength([1, 2, 3]);  // 3

在这里,T被约束为HasLength接口的子类型,因此只有具有length属性的类型才能传递给getLength函数。

4. 泛型应用场景:

  • 数据结构通用性: 泛型可用于创建通用的数据结构,如数组、列表或字典,以处理各种数据类型。
  • 函数重用性: 泛型函数可以重用于不同数据类型的参数,减少代码重复。
  • 类型安全性: 使用泛型可以增加类型检查的安全性,减少潜在的运行时错误。

5. 示例:使用泛型实现堆栈数据结构:

以下是一个使用泛型实现的堆栈数据结构示例:

typescript
class Stack<T> {
    private items: T[] = [];

    push(item: T): void {
        this.items.push(item);
    }

    pop(): T | undefined {
        return this.items.pop();
    }
}

const numberStack = new Stack<number>();
numberStack.push(1);
numberStack.push(2);
console.log(numberStack.pop());  // 2

const stringStack = new Stack<string>();
stringStack.push("Hello");
stringStack.push("World");
console.log(stringStack.pop());  // "World"

在这个示例中,Stack类是一个泛型类,可以用于存储不同类型的数据。

总之,TypeScript中的泛型是一个非常强大的工具,可以增加代码的灵活性和安全性。它允许我们编写可重用的代码来处理各种数据类型,同时保持类型检查的好处。通过类型约束,我们可以进一步控制泛型的范围,以满足特定需求。在编写通用代码或处理多种数据类型的情况下,泛型是一个不可或缺的工具。