TypeScript泛型使用 | 豆包MarsCode AI刷题

58 阅读2分钟

TypeScript 作为 JavaScript 的超集,它在保留了 JavaScript 的灵活性的同时,通过引入静态类型系统增强了代码的可靠性和开发体验,提升了代码质量,使代码运行更加稳定。泛型是 TypeScript 中一个非常重要的特性,它允许我们在保持类型安全的同时编写可重用的代码组件。以下是一些关于 TypeScript 中泛型的使用方法和场景的实践记录,以及如何使用类型约束来增加代码的灵活性和安全性。

泛型的基本使用

1. 泛型函数

泛型函数可以处理不同类型的数据,而无需为每种类型重写函数。

function identity<T>(arg: T): T {
    return arg;
}
let output1 = identity<string>("Hello World");
let output2 = identity("Hello World"); // 类型推论

2. 泛型接口

泛型接口可以定义一个带有泛型的对象类型。

interface GenericIdentityFn<T> {
    (arg: T): T;
}
function identity<T>(arg: T): T {
    return arg;
}
let myIdentity: GenericIdentityFn<number> = identity;

3. 泛型类

泛型类可以创建一个可以在多个类型上工作的组件。

class GenericNumber<T> {
    zeroValue: T;
    add: (x: T, y: T) => T;
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };

泛型的使用场景

1. 数组和其他集合

泛型可以用来创建可重用的数组类型。

function loggingIdentity<T>(arg: T[]): T[] {
    console.log(arg.length);  // Array has a .length, so no more error
    return arg;
}

2. 函数工厂

泛型可以用来创建返回不同类型函数的工厂函数。

function createLogger<T>(moduleName: string): (message: T) => void {
    return function(message: T) {
        console.log(`${moduleName}: ${message}`);
    }
}
const logNumber: (message: number) => void = createLogger("NumberLogger");
const logString: (message: string) => void = createLogger("StringLogger");

类型约束

类型约束可以让我们指定泛型可以是哪些类型,从而增加代码的灵活性和安全性。

1. 使用 extends 约束泛型

interface Lengthwise {
    length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length);  // Now we know it has a .length property, so no more error
    return arg;
}

2. 在泛型中使用类类型

可以使用泛型来约束类类型,从而创建可以在多个类上工作的组件。

function createInstance<A extends new (...args: any[]) => any>(ctor: A): InstanceType<A> {
    return new ctor();
}
class BeeKeeper {
    hasMask: boolean = true;
}
class ZooKeeper {
    nametag: string = 'Mikle';
}
class Animal {
    numLegs: number = 4;
}
class Bee extends Animal {
    keeper: BeeKeeper = new BeeKeeper();
}
class Lion extends Animal {
    keeper: ZooKeeper = new ZooKeeper();
}
function createInstance<A extends Animal>(ctor: new () => A): A {
    return new ctor();
}
createInstance(Lion).keeper.nametag;  // typechecks!
createInstance(Bee).keeper.hasMask;   // typechecks!

通过上述的实践记录,我们可以看到泛型在 TypeScript 中的强大功能,它不仅能够提高代码的复用性,还能在编译时期提供类型检查,从而提高代码的安全性和可维护性。类型约束的使用则进一步增强了泛型的能力,允许我们定义更加精确的 API。