TypeScript中Mixin调用构造函数时参数不被识别的问题排查
TypeScript Mixin构造函数参数类型错误问题解析
问题场景
使用Mixin生成匿名类时,Mixin的构造函数明明定义了可变参数,但创建实例时TypeScript报错Expected 0 arguments, but got 1。给被装饰的类添加显式构造函数能解决问题,但想了解报错原因,以及无需为每个扩展类手动添加构造函数的解决方案。
示例代码:
type Constructor<T = {}> = new (...args: any[]) => T; function mixin<T extends Constructor>(Base: T) { return class extends Base { constructor(...args: any[]) { super(...args); } }; } @mixin class TestCase { } new TestCase(1) // <- 报错:Expected 0 arguments, but got 1.
问题原因
当类没有显式定义构造函数时,TypeScript会自动推断其构造函数类型为无参构造函数(new () => TestCase)。虽然你的Mixin在运行时能接收任意参数并传递给父类,但TypeScript的类型系统并没有正确关联Mixin返回类与基类的构造函数参数信息——它会基于基类推断出的无参构造函数,判定返回的类也只能无参实例化,因此触发类型错误。
解决方法
无需给每个扩展类添加构造函数,只需调整Mixin的类型定义,让它正确保留基类的构造函数参数信息:
方案1:精确继承基类构造参数
通过ConstructorParameters提取基类的构造函数参数类型,让返回类的构造函数完全继承该类型:
type Constructor<T = {}> = new (...args: any[]) => T; function mixin<T extends Constructor>(Base: T) { return class extends Base { constructor(...args: ConstructorParameters<T>) { super(...args); } } as new (...args: ConstructorParameters<T>) => InstanceType<T>; } @mixin class TestCase { } new TestCase(1); // 不再报错
方案2:放宽构造参数类型约束
如果希望Mixin返回的类能接收任意参数(匹配原运行时逻辑),可以显式指定返回类的构造函数为可变参数类型:
type Constructor<T = {}> = new (...args: any[]) => T; function mixin<T extends Constructor>(Base: T) { return class extends Base { constructor(...args: any[]) { super(...args); } } as new (...args: any[]) => InstanceType<T>; } @mixin class TestCase { } new TestCase(1); // 不再报错
这两种方案都能让TypeScript类型系统正确识别Mixin返回类的构造函数参数,无需为每个被装饰类手动添加构造函数。
内容的提问来源于stack exchange,提问作者FastIndian
相关产品推荐
相关产品推荐

