TypeScript动态赋值对象已知键报错:类型'any'无法赋值给'never'
TypeScript动态赋值对象已知键时"Type 'any' is not assignable to type 'never'"问题解决
这个错误本质是TypeScript的类型收窄逻辑导致的:当用string类型的attributeProp访问对象属性时,即便做了类型断言,因为attributeValue是any类型,且对象不同键的类型可能存在冲突,TS会把目标属性的类型推断为所有键类型的交叉类型,最终变成never,从而抛出赋值错误。另外keyof attribute本身是错误写法——keyof只能作用于类型,不能作用于具体的变量实例。
下面是几种可靠的解决方法:
方法一:用泛型绑定键与值的类型(推荐)
通过泛型让attributeProp严格对应对象的键,同时让attributeValue自动匹配对应键的类型,从根源上避免类型不匹配问题:
// 示例对象类型 type TObjectTypeAttribute = { name: string; age: number; status: boolean; }; const onChange = <K extends keyof TObjectTypeAttribute>( attribute: TObjectTypeAttribute, attributeProp: K, attributeValue: TObjectTypeAttribute[K] ) => { attribute[attributeProp] = attributeValue; // 无类型错误 }; // 使用示例 const attr: TObjectTypeAttribute = { name: "", age: 0, status: false }; onChange(attr, "name", "Tom"); // 合法赋值 onChange(attr, "age", 25); // 合法赋值 onChange(attr, "age", "25"); // TS直接报错,类型不匹配
如果需要支持任意类型的对象,可以用通用泛型版本:
const onChange = <T, K extends keyof T>( attribute: T, attributeProp: K, attributeValue: T[K] ) => { attribute[attributeProp] = attributeValue; };
方法二:强制类型断言(仅在无法用泛型时使用)
如果attributeProp必须是string类型(比如从外部动态获取的字符串),可以先判断键的合法性,再用双重断言绕过类型检查——但注意这种方式会丢失TypeScript的类型保护,必须确保attributeValue的类型和目标键一致:
const onChange = ( attribute: TObjectTypeAttribute, attributeProp: string, attributeValue: any ) => { if (attributeProp in attribute) { attribute[attributeProp as keyof TObjectTypeAttribute] = attributeValue as TObjectTypeAttribute[keyof TObjectTypeAttribute]; } };
内容的提问来源于stack exchange,提问作者Игор Ташевски
相关产品推荐
相关产品推荐

