TypeScript循环赋值对象属性出现never类型错误的解决方法
解决TypeScript遍历对象属性赋值时的never类型错误
问题原因
你推测的完全正确:TypeScript在循环中无法精准跟踪每个key对应的具体属性类型。它只知道key属于keyof Pet(即'name' | 'age'),因此右侧pet1[key]的类型会被推断为string | number;而左侧pet2[key]的类型会被解析为所有属性类型的交集——string & number,也就是never,最终导致类型不匹配报错。
解决方案
方案1:类型断言快速修复
直接给右侧值断言为左侧属性的类型,明确告诉TypeScript类型是匹配的:
type Pet = { name: string; age: number }; const pet1: Pet = { name: 'Speedy', age: 4 }; const pet2: Pet = { name: 'Bibi', age: 5 }; const keys = Object.keys(pet1) as Array<keyof Pet>; for (const key of keys) { pet2[key] = pet1[key] as typeof pet2[key]; }
方案2:泛型函数让TypeScript精准跟踪类型
封装一个通用泛型函数,让TypeScript能为每个key推断出具体的属性类型:
type Pet = { name: string; age: number }; const pet1: Pet = { name: 'Speedy', age: 4 }; const pet2: Pet = { name: 'Bibi', age: 5 }; function copyProperties<T>(target: T, source: T) { const keys = Object.keys(target) as Array<keyof T>; for (const key of keys) { target[key] = source[key]; } } copyProperties(pet2, pet1);
方案3:用Object.assign简化操作
如果只是需要把源对象的所有属性覆盖到目标对象,直接使用TypeScript原生支持的Object.assign即可,无需手动写循环:
type Pet = { name: string; age: number }; const pet1: Pet = { name: 'Speedy', age: 4 }; const pet2: Pet = { name: 'Bibi', age: 5 }; Object.assign(pet2, pet1);
针对Svelte场景的解决办法
你的Svelte store订阅场景本质是同样的问题,用泛型函数或类型断言都能解决,示例如下:
// 假设类型定义(根据实际场景替换) type SelectedFilters = { [key: string]: Writable<any>; }; const selected: SelectedFilters = {}; const filterColumns: Array<keyof SelectedFilters> = []; // 泛型函数处理 function syncFilterStores<T extends Record<string, Writable<any>>>(selected: T, columns: Array<keyof T>) { for (const column of columns) { selected[column].subscribe(($value) => { $selected[column] = $value as typeof $selected[column]; }); } } syncFilterStores(selected, filterColumns);
内容的提问来源于stack exchange,提问作者Windar
相关产品推荐
相关产品推荐

