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

75 阅读2分钟

TypeScript 类、泛型的使用实践记录

1. 泛型函数

泛型函数是使用泛型的常见方式之一,它允许你编写适用于不同类型的数据的函数。例如,下面是一个简单的泛型函数,用于交换两个变量的值:

function swap<T>(a: T, b: T): void {
    let temp: T = a;
    a = b;
    b = temp;
}

let x = 5, y = 10;
swap(x, y); // x 现在是 10,y 现在是 5

2. 类中的泛型

泛型也可以在类中使用,允许你在类中处理不同类型的数据。例如,下面是一个简单的泛型类,用于创建一个存储任意类型元素的堆栈:

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(5);
numberStack.push(10);
console.log(numberStack.pop()); // 输出 10

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

3. 泛型约束

有时候,你希望对泛型参数施加一些限制,以确保代码的安全性和正确性。这就是泛型约束的用途。例如,你可以使用泛型约束来要求传入的类型具有某些属性或方法:

interface Lengthable {
    length: number;
}

function printLength<T extends Lengthable>(item: T): void {
    console.log(item.length);
}

printLength("Hello"); // 输出 5
printLength([1, 2, 3]); // 输出 3

4. 使用默认类型

你还可以为泛型参数提供默认类型,以便在调用时如果没有显式指定类型,就会使用默认类型:

function getValueOrDefault<T = number>(value: T, defaultValue: T): T {
    return value !== undefined ? value : defaultValue;
}

const result = getValueOrDefault(undefined, 10); // 默认为 10

5. 多个泛型参数

函数、类等可以有多个泛型参数,用途从而变得更加灵活。例如:

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

const merged = merge({ a: 1 }, { b: 2 });
// merged 的类型为 { a: number, b: number }

在 TypeScript 中,泛型的使用能够帮助你更好地抽象和重用代码,同时也能提供更强的类型安全性。根据具体的场景,你可以选择合适的泛型使用方式以及是否需要使用类型约束,从而提高代码的质量和可维护性。