TypeScript:更新类型为never的对象属性值报错解决方案咨询
问题与解决方案
我看过Bobby Hadz对同类型数组相关错误的解释,但没找到针对包含不同类型属性的对象的解决方案。当前遇到的TypeScript错误如下:
Type 'string | number | boolean' is not assignable to type 'never'. Type 'string' is not assignable to type 'never'.
引发错误的代码:
const geometryCopy : geometryTypes = {... geometryValues} //Append the new value to the object if(geometryCopy?.[attributeName]) geometryCopy[attributeName] = newValue
其中attributeName的类型为keyof geometryType,该错误已在TypeScript Playground中复现。
解决方法
1. 类型断言明确类型匹配
通过类型断言告知TypeScript,newValue的类型与目标属性的类型一致:
if(geometryCopy?.[attributeName]) { geometryCopy[attributeName] = newValue as typeof geometryCopy[typeof attributeName]; }
⚠️ 注意:这种方式需要你确保newValue确实符合目标属性的类型,否则可能引发运行时错误。
2. 泛型工具函数强制类型约束
创建泛型函数来约束属性名和对应值的类型,从根源避免类型不匹配:
function updateGeometryAttribute<T extends keyof geometryType>( obj: geometryType, key: T, value: geometryType[T] ) { obj[key] = value; } // 使用示例 if(geometryCopy?.[attributeName]) { updateGeometryAttribute(geometryCopy, attributeName, newValue as geometryType[typeof attributeName]); }
泛型会自动关联key和value的类型,确保赋值的安全性。
3. 类型守卫验证值类型
通过自定义类型守卫提前验证newValue是否属于对象属性的合法类型范围:
type GeometryAttributeValue = geometryType[keyof geometryType]; function isGeometryAttributeValue(value: unknown): value is GeometryAttributeValue { const validTypes = ['string', 'number', 'boolean']; return validTypes.includes(typeof value); } if(geometryCopy?.[attributeName] && isGeometryAttributeValue(newValue)) { geometryCopy[attributeName] = newValue as typeof geometryCopy[typeof attributeName]; }
未遵循的最佳实践
- 忽略动态属性的类型关联:当对象属性类型多样时,直接给
keyof类型的属性赋值宽泛的联合类型,TypeScript无法推断具体属性的类型,因此抛出never错误。 - 缺乏类型安全的动态赋值:动态修改对象属性时,未通过泛型、类型断言或类型守卫确保值与属性类型匹配,违背了TypeScript的类型安全原则。
- 依赖宽泛的联合类型:使用
string | number | boolean这类宽泛的联合类型作为newValue的类型,没有与对象的具体属性类型绑定,导致类型推断失败。
内容的提问来源于stack exchange,提问作者QuirkyGoodFriend
相关产品推荐
相关产品推荐

