如何用TypeScript实现从Partial<Class>循环赋值类实例属性
解决TypeScript中populate方法的类型不匹配问题
你遇到的Type 'string' is not assignable to type 'never'错误,本质是TypeScript在循环遍历Partial<Test>的键时,无法确定当前键对应的this[i]和data[i]类型严格匹配——因为this[i]可能是number或string,data[i]也可能是两者之一,TS无法保证类型对齐,所以会把this[i]的类型推断为never(两种类型的无交集部分)。
下面提供两种符合TypeScript规范的解决方案,都不需要使用//@ts-ignore或[key: string]: any:
方案1:用泛型函数追踪属性类型对应关系
把循环内的赋值逻辑封装成泛型函数,让TypeScript明确每个键的类型绑定:
class Test { a: number = 1; b: string = 'B'; populate(data: Partial<Test>) { // 泛型函数:明确键与对应值的类型关系 const assignValidProp = <K extends keyof Test>(key: K, value: Test[K]) => { this[key] = value; }; for (const i in data) { const key = i as keyof Test; const value = data[key]; // 保留原有生产环境的校验逻辑 if (value !== undefined && Object.prototype.hasOwnProperty.call(this, key)) { assignValidProp(key, value as Test[typeof key]); } } } } const testInstance = new Test(); testInstance.populate({ a: 2, b: 'bar' });
方案2:先过滤有效属性再用Object.assign赋值
如果可以用Object.assign替代手动循环赋值,先过滤出符合校验条件的属性再赋值,类型推断会更顺畅:
class Test { a: number = 1; b: string = 'B'; populate(data: Partial<Test>) { const validProps: Partial<Test> = {}; for (const i in data) { const key = i as keyof Test; const value = data[key]; if (value !== undefined && Object.prototype.hasOwnProperty.call(this, key)) { validProps[key] = value; } } Object.assign(this, validProps); } } const testInstance = new Test(); testInstance.populate({ a: 2, b: 'bar' });
两种方案都保留了你原有生产环境的校验逻辑,同时完全符合TypeScript的类型规范。
内容的提问来源于stack exchange,提问作者Robin Schambach
相关产品推荐
相关产品推荐

