TypeScript类装饰器构造函数参数的泛型类型适配问题
解决方案
要解决这个问题,你可以用泛型构造函数类型替代Function,它能完美适配不同类的类型,同时满足TypeScript的类型检查要求,还能避免lint报错。
步骤1:给装饰器配置定义类型(可选但推荐)
先给传入装饰器的配置参数明确类型,让类型检查更严谨:
type StudentConfig = { course: string; };
步骤2:用泛型重构装饰器
把装饰器的返回函数改成泛型函数,target的类型定义为new (...args: any[]) => T——这个类型表示“能创建T类型实例的构造函数”,T可以适配任意类的实例类型:
function Student(config: StudentConfig) { return function <T extends {}>(target: new (...args: any[]) => T) { // 用点语法访问prototype,比字符串索引更规范 target.prototype.tValue = "some value"; }; }
优化:让装饰器添加的属性被类型系统识别(可选)
如果希望Person、People的实例能被TypeScript自动识别出tValue属性,可以通过接口合并实现:
// 定义装饰器添加的属性接口 interface StudentDecorated { tValue: string; } function Student(config: StudentConfig) { return function <T extends {}>(target: new (...args: any[]) => T & StudentDecorated) { target.prototype.tValue = "some value"; }; } // 使用装饰器的类 @Student({ course: "Angular 2" }) class Person {} @Student({ course: "Angular 15" }) class People {} // 此时类型系统能识别p有tValue属性,不会报错 const p = new Person(); console.log(p.tValue);
这样修改后,既摆脱了Function类型的局限,又能完美适配不同类,同时保持了TypeScript的类型安全性。
内容的提问来源于stack exchange,提问作者Robin Chugh
相关产品推荐
相关产品推荐

