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

如何声明Module装饰器的imports数组为被修饰类的类型?

解决Module装饰器的类型声明错误

问题核心

你碰到的错误根源:

  • Module是你定义的装饰器函数(值),不能直接当作类型使用
  • 未明确声明被装饰类的类型,导致TypeScript无法识别imports数组的元素类型

正确的类型声明写法

先定义一个代表「被Module装饰的类」的类型,再用这个类型约束imports属性:

// 定义被Module装饰的类的类型:任意可实例化的类构造函数
export type ModuleClass = new (...args: any[]) => any;

export interface ModuleOptions {
  imports?: ModuleClass[];
}

// 修复装饰器的泛型声明,同时设置参数默认值
export function Module(options: Partial<ModuleOptions> = {}) {
  return <T extends ModuleClass>(target: T) => {
    return class extends target {};
  };
}

验证使用

现在可以正常使用装饰器,TypeScript会自动校验imports的类型:

@Module()
export class MyModule {}

@Module({ imports: [MyModule] })
export class MyOtherModule {}

// 错误示例:传入非Module装饰的类会触发TypeScript报错
class NotAModule {}
@Module({ imports: [NotAModule] }) // 类型错误:NotAModule不符合ModuleClass类型
export class BadModule {}

可选优化

如果需要给被装饰类统一添加模块元数据,可以扩展ModuleClass类型:

// 定义带有模块元数据的类类型
export type ModuleClass = new (...args: any[]) => {
  moduleMetadata?: Record<string, any>;
};

// 在装饰器中注入元数据
export function Module(options: Partial<ModuleOptions> = {}) {
  return <T extends ModuleClass>(target: T) => {
    const decoratedClass = class extends target {};
    decoratedClass.moduleMetadata = { imports: options.imports };
    return decoratedClass;
  };
}

内容的提问来源于stack exchange,提问作者Get Off My Lawn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 06:35:37