如何声明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
相关产品推荐
相关产品推荐

