You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中如何传递实现DataAdapterInterface的类而非实例?

问题描述

我定义了如下接口:

interface DataAdapterInterface {
    init(url: string): void
    execute(command: string, values?: string[]): Promise<any>
    insert(items: any[]): Promise<any>
    find(items: any[]): Promise<any>
    update(items: any[]): Promise<boolean>
    remove(items: any[]): Promise<boolean>
}

还有一个装饰器函数:

export function protocol(protocol: string) {
    return function (constructor: Function) {
        constructor['__protocol'] = protocol;
    };
}

接着创建了实现该接口的类:

@protocol("mysql")
export class MySQLAdapter implements DataAdapterInterface {
    init(url: string): void {}
    execute(command: string): Promise<any> {}
    insert(item: any[]): Promise<any> {}
    find(item: any[]): Promise<any> {}
    update(item: any[]): Promise<boolean> {}
    remove(item: any[]): Promise<boolean> {}
}

另外有一个注册函数:

export function register(adapter: DataAdapterInterface) { 
    ConnectionFactory.register(adapter['__protocol'], adapter)
}

执行register(MySQLAdapter);时,TypeScript报错提示MySQLAdapter不是DataAdapterInterface类型。JavaScript运行正常,把参数改成any能消除编译错误,但我希望限制参数仅为实现DataAdapterInterface的类,请问有没有无需实例化类也不用any类型的传递方式?

解决方案

问题核心是:你传入的是类的构造函数,但register的参数类型定义的是接口的实例类型,TypeScript的类型检查自然不通过。只需调整参数类型为对应接口的构造函数类型即可解决。

1. 定义构造函数类型

先声明一个类型,代表能创建DataAdapterInterface实例的构造函数:

type DataAdapterConstructor = new () => DataAdapterInterface;

2. 优化装饰器类型(可选,提升严谨性)

把原装饰器中宽泛的Function类型替换为上面的构造函数类型,让类型检查更严格:

export function protocol(protocol: string) {
    return function (constructor: DataAdapterConstructor) {
        constructor['__protocol'] = protocol;
    };
}

3. 修改register函数的参数类型

将register的参数类型从DataAdapterInterface改为DataAdapterConstructor,并调整内部逻辑(现在接收的是构造函数而非实例):

export function register(adapterConstructor: DataAdapterConstructor) { 
    ConnectionFactory.register(adapterConstructor['__protocol'], adapterConstructor)
}

4. 调用验证

现在执行register(MySQLAdapter);不会再有类型错误,同时TypeScript会自动校验传入的类是否实现了DataAdapterInterface,完全满足“无需实例化、不用any类型”的需求。

额外优化:为构造函数添加协议属性类型

如果想让__protocol属性获得类型提示,可以扩展构造函数类型:

type DataAdapterConstructor = new () => DataAdapterInterface & {
    __protocol?: string;
};

这样访问adapterConstructor['__protocol']时,TypeScript会识别该属性的存在,不会出现类型报错。

内容的提问来源于stack exchange,提问作者Magician

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 05:16:11