TypeScript 类、泛型的使用实践记录:探讨TypeScript中的泛型的使用方法和场景,以及如何使用类型约束来增加代码的灵活性和安全性

49 阅读2分钟

TypeScript 中的泛型是一种强大的工具,它允许你在定义函数、类或接口时使用类型参数,从而增加代码的灵活性和安全性。泛型可以帮助你在编写可重用的代码时,避免重复定义相似的类型,同时还能确保类型安全。

泛型的基本使用

泛型最常见的使用场景是在函数中。通过使用泛型,你可以编写一个可以处理多种类型的函数,而不需要为每种类型都编写一个单独的函数。

示例:泛型函数

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

let output1 = identity<string>("Hello"); // 明确指定类型
let output2 = identity("World"); // 类型推断

在这个例子中,identity 函数使用了泛型类型参数 T,它可以接受任何类型的参数,并返回相同类型的值。

泛型类

泛型类允许你在类的定义中使用类型参数,从而使类的实例可以处理多种类型。

示例:泛型类

class Box<T> {
    private value: T;

    constructor(value: T) {
        this.value = value;
    }

    getValue(): T {
        return this.value;
    }

    setValue(value: T): void {
        this.value = value;
    }
}

let box1 = new Box<number>(123);
console.log(box1.getValue()); // 输出: 123

let box2 = new Box<string>("Hello");
console.log(box2.getValue()); // 输出: Hello

在这个例子中,Box 类使用了泛型类型参数 T,它可以存储和操作任何类型的值。

类型约束

有时候,你可能希望泛型类型参数满足某些特定的条件。TypeScript 允许你使用类型约束来限制泛型类型参数的范围。

示例:类型约束

interface Lengthwise {
    length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length); // 现在我们知道 arg 有一个 length 属性
    return arg;
}

loggingIdentity("Hello"); // 正确,字符串有 length 属性
loggingIdentity([1, 2, 3]); // 正确,数组有 length 属性
loggingIdentity(42); // 错误,数字没有 length 属性

在这个例子中,loggingIdentity 函数使用了类型约束 T extends Lengthwise,这意味着 T 必须是一个具有 length 属性的类型。

泛型接口

泛型接口允许你在接口中使用类型参数,从而使接口可以处理多种类型。

示例:泛型接口

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

let pair: Pair<number, string> = { first: 1, second: "Hello" };
console.log(pair.first); // 输出: 1
console.log(pair.second); // 输出: Hello

在这个例子中,Pair 接口使用了两个泛型类型参数 TU,它可以表示任何类型的键值对。

总结

泛型是 TypeScript 中一个非常强大的特性,它可以帮助你编写更加灵活和类型安全的代码。通过使用泛型,你可以避免重复定义相似的类型,同时还能确保类型安全。类型约束则进一步增强了泛型的能力,允许你限制泛型类型参数的范围,从而使代码更加健壮。

希望这些示例和解释能帮助你更好地理解和使用 TypeScript 中的泛型。如果你有更多问题或需要进一步的解释,请随时提问!