TypeScript类构造函数中this[key]被推断为never类型的排查与解决
TypeScript循环赋值类属性时
never类型推断错误的原因与解决方法 问题重现
以下代码可正常编译运行,但VSCode(Code - OSS 1.73.0)会在this[key] = props[key]处报错,提示Type 'string | number' is not assignable to type 'never':
type ClassProps = { a: number, b: string, } class Example implements ClassProps { public a: number public b: string constructor(props: ClassProps) { let key: keyof ClassProps for(key in props) { this[key] = props[key] // 此处报never类型错误 } } }
错误原因
TypeScript的类型系统在这种循环场景下,无法跟踪key的具体类型与this[key]、props[key]的关联关系:
key的类型是keyof ClassProps,也就是"a" | "b"的联合类型- 访问
this[key]时,TypeScript会计算所有属性类型的交集:number & string,这两个类型没有重叠部分,结果就是never - 而
props[key]的类型是number | string,自然无法赋值给never类型的变量,因此报错
另外你提到的!运算符仅能解决「属性未被初始化」的提示,无法处理这个never类型推断的问题。
解决方法
这里提供几种不丢失类型检查的解决方案:
方案1:使用Object.assign(最简洁)
直接用Object.assign把props的属性批量赋值给实例,TypeScript能正确识别这种操作的类型:
type ClassProps = { a: number, b: string, } class Example implements ClassProps { public a: number public b: string constructor(props: ClassProps) { Object.assign(this, props) } }
方案2:泛型辅助函数
把赋值逻辑抽成泛型函数,利用泛型保留key的具体类型关联:
type ClassProps = { a: number, b: string, } class Example implements ClassProps { public a: number public b: string constructor(props: ClassProps) { const assignProp = <K extends keyof ClassProps>(key: K) => { this[key] = props[key] } for(const key in props) { assignProp(key as keyof ClassProps) } } }
方案3:类型断言(谨慎使用)
如果一定要保留循环写法,可以用类型断言告诉TypeScriptthis[key]的类型与props[key]一致,前提是你能保证两者结构完全匹配:
type ClassProps = { a: number, b: string, } class Example implements ClassProps { public a: number public b: string constructor(props: ClassProps) { let key: keyof ClassProps for(key in props) { this[key] = props[key] as typeof this[key] } } }
内容的提问来源于stack exchange,提问作者Arsylum
相关产品推荐
相关产品推荐

