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

TypeScript泛型工厂模式基类控制器报类型当值使用错误

问题原因

TypeScript泛型参数仅在编译阶段做类型校验,编译为JavaScript后会被完全擦除,运行时不存在对应的值,因此直接写new X()会触发报错:

'X' only refers to a type, but is being used as a value here

之前用抽象模型基类的思路没解决问题,核心是没有把模型的构造函数(运行时可访问的值)传入基类逻辑,泛型本身无法携带运行时的构造器引用。另外注意纯接口类型同样会在编译后擦除,没有运行时构造逻辑,无法直接实例化,需要配套实现类才能创建实例。

可行实现方案

核心思路是显式传入模型对应的构造函数引用,让运行时可以拿到构造器完成实例初始化,同时保留完整的类型校验能力。

// 定义无参模型构造函数的类型约束
type ModelCtor<T> = new () => T;

// 模型抽象基类,所有可实例化业务模型继承该类
abstract class BaseModel {}

// 业务模型A
class ModelA extends BaseModel {
    propA: string;
    propB?: number;
    propC?: number;
    constructor() {
        super();
        this.propA = "here";
    }
}

// 原接口ModelB无运行时实现,补充对应实现类用于实例化
class ModelBImpl extends BaseModel {
    propA: string;
    propB: number;
    propC: number;
    constructor() {
        super();
        this.propA = "defaultB";
        this.propB = 0;
        this.propC = 0;
    }
}
interface ModelB {
    propA: string;
    propB: number;
    propC: number;
}

// 泛型基类控制器
class BaseController<T extends BaseModel> {
    private _model: T;

    constructor(payload: T) {
        this._model = payload;
    }

    // 基类静态工厂方法,接收模型构造器完成初始化
    static create<T extends BaseModel>(
        this: new (payload: T) => BaseController<T>,
        modelCtor: ModelCtor<T>
    ): BaseController<T> {
        const model = new modelCtor();
        return new this(model);
    }

    // 通用模型访问方法,可按需扩展其他通用业务逻辑
    get model(): T {
        return this._model;
    }
}

// 业务控制器A,绑定ModelA构造器
class ModelAController extends BaseController<ModelA> {
    static create(): ModelAController {
        return super.create(ModelA) as ModelAController;
    }
}

// 业务控制器B,绑定ModelBImpl构造器
class ModelBController extends BaseController<ModelBImpl> {
    static create(): ModelBController {
        return super.create(ModelBImpl) as ModelBController;
    }
}

// 调用示例:直接通过工厂方法创建控制器,内部已自动初始化带默认值的模型
const aController = ModelAController.create();
console.log(aController.model.propA); // 输出 "here"
const bController = ModelBController.create();
console.log(bController.model.propB); // 输出 0
方案说明
  • 所有类型校验逻辑完整保留,调用方拿到的控制器、内部模型的类型提示完全准确
  • 业务控制器仅需在静态create方法中绑定一次对应模型的构造器,无重复样板代码
  • 若需要支持带参数的模型构造,只需修改ModelCtor的类型定义、调整工厂方法传参即可快速适配
  • 禁止直接使用纯接口作为可实例化的模型泛型参数,接口无运行时实现,必须提供对应构造逻辑(实现类/工厂函数)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 02:48:20