深入理解 JS TypeScript 泛型

2025-12-27 9072阅读

在 JavaScript 编程中,TypeScript 为我们带来了强大的类型系统,而泛型则是其中一个非常重要的特性。它允许我们编写灵活且可复用的代码,在不同的数据类型上保持类型安全。

泛型的基本概念

泛型就像是一个“类型的占位符”。例如,我们定义一个函数,它可以接收不同类型的参数并返回相同类型的结果。在没有泛型时,我们可能会使用 any 类型,但这会失去类型检查的优势。而使用泛型,我们可以这样写:

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

这里的 <T> 就是泛型类型参数。T 可以代表任何类型,当我们调用 identity 函数时,TypeScript 会根据传入的参数类型自动推断 T 的具体类型。比如:

let num = identity<number>(5); // T 被推断为 number
let str = identity('hello'); // T 被推断为 string

泛型在接口中的应用

我们也可以在接口中使用泛型。假设我们有一个表示数据存储的接口:

interface DataStore<T> {
    data: T;
    setData(data: T): void;
    getData(): T;
}

然后我们可以创建不同类型的 DataStore 实例:

class NumberStore implements DataStore<number> {
    constructor(public data: number) {}
    setData(data: number): void {
        this.data = data;
    }
    getData(): number {
        return this.data;
    }
}

class StringStore implements DataStore<string> {
    constructor(public data: string) {}
    setData(data: string): void {
        this.data = data;
    }
    getData(): string {
        return this.data;
    }
}

泛型约束

有时候,我们希望泛型类型满足一定的条件,这就需要用到泛型约束。比如,我们希望传入的类型有一个 length 属性(像字符串、数组等):

interface Lengthwise {
    length: number;
}

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

let strLength = getLength('test'); // 正确,字符串有 length 属性
// let numLength = getLength(5); // 错误,数字没有 length 属性

泛型类

除了函数和接口,类也可以是泛型的。例如一个简单的栈类:

class Stack<T> {
    private items: T[] = [];
    push(item: T): void {
        this.items.push(item);
    }
    pop(): T | undefined {
        return this.items.pop();
    }
}

let numberStack = new Stack<number>();
numberStack.push(10);
let poppedNum = numberStack.pop();

let stringStack = new Stack<string>();
stringStack.push('one');
let poppedStr = stringStack.pop();

泛型与类型推断

TypeScript 强大的类型推断机制在泛型中也发挥着重要作用。很多时候,我们不需要显式地指定泛型类型参数,TypeScript 会根据上下文自动推断。比如:

function createArray<T>(...items: T[]): T[] {
    return items;
}

let numArray = createArray(1, 2, 3); // 自动推断 T 为 number
let strArray = createArray('a', 'b'); // 自动推断 T 为 string

总结

JS TypeScript 泛型为我们提供了编写高度可复用、类型安全代码的能力。无论是在函数、接口、类还是其他场景中,合理运用泛型可以让我们的代码更加灵活和健壮。通过理解泛型的基本概念、约束以及与类型推断的配合,我们能够更好地利用 TypeScript 的优势,编写出高质量的 JavaScript 代码。随着项目规模的增大,泛型的价值会更加凸显,它帮助我们减少重复代码,提高代码的可维护性和可读性。

文章版权声明:除非注明,否则均为Dark零点博客原创文章,转载或复制请以超链接形式并注明出处。