为何TypeScript会在类构造函数中生成void 0赋值语句?
解决NSwag生成TypeScript类属性被覆盖为undefined的问题
问题根源
NSwag生成的Derived类会显式声明name这类实例属性,而父类ModelBase通过for循环动态将传入的data属性赋值到实例上。TypeScript 5.2.2版本的编译器无法识别这种动态赋值逻辑,会自动在子类构造函数的super(data)之后添加this.name = void 0的初始化语句,直接覆盖父类构造函数中完成的赋值。
可行解决方案
1. 修改NSwag生成配置,避免子类显式声明属性
在NSwag的TypeScript客户端生成设置中做以下调整:
- 启用
UseBaseClassConstructor(若存在该选项),让子类完全依赖父类构造函数处理属性赋值 - 或者将
GenerateProperties设为false,改为生成仅包含接口定义的客户端,结合工厂函数创建实例(更贴合TypeScript的类型使用习惯) - 若用NSwag CLI,可添加参数
--typescript-generate-properties false,或在nswag.json中配置:
{ "typescriptGenerator": { "generateProperties": false, "generateInterfaces": true } }
2. 调整TypeScript编译选项
在tsconfig.json中关闭strictPropertyInitialization,编译器就不会强制要求属性在构造函数中显式初始化,也就不会生成覆盖赋值的语句:
{ "compilerOptions": { "strictPropertyInitialization": false } }
如果需要更精细的控制,也可以在ModelBase类上添加索引签名,让编译器认可动态属性的合法性:
export class ModelBase { [key: string]: any; // 添加索引签名 constructor(data?: any) { if (data) { for (const key in data) { if (data.hasOwnProperty(key)) { this[key] = data[key]; } } } } }
3. 手动修改生成的子类代码(临时应急方案)
如果暂时无法修改NSwag配置或编译选项,可以手动删除Derived类中显式声明的属性(比如name: string;这类行),让子类完全依赖父类的动态赋值。注意这种方法每次重新生成代码后都需要重复操作,仅适合临时测试场景。
内容的提问来源于stack exchange,提问作者Andrew Downum
相关产品推荐
相关产品推荐

