TypeScript:如何以类型安全的泛型方式更新对象属性?
类型安全的对象属性更新方案
问题根源
never类型错误:当key为keyof ISettings联合类型时,TypeScript要求赋值的value必须满足所有属性类型的交集,而boolean、number、'EN' | 'NL'的交集是never,导致无法直接赋值。- 类型校验缺失:
value用any定义完全失去类型约束,无法保证传入值与目标属性类型一致。
针对性解决:泛型绑定key与value类型
通过泛型参数K将key和对应属性的类型关联起来,让TypeScript精准推断value的合法类型:
interface ISettings { isOpen: boolean; width: number; language: 'EN' | 'NL'; } const settings: ISettings = { isOpen: true, width: 300, language: 'EN' }; // 泛型K继承keyof ISettings,value类型自动绑定为ISettings[K] function updateSettings<K extends keyof ISettings>(key: K, value: ISettings[K]) { settings[key] = value; } // 合法调用(类型完全匹配) updateSettings('isOpen', false); updateSettings('width', 400); updateSettings('language', 'NL'); // 非法调用会触发TypeScript错误 updateSettings('isOpen', 123); // 错误:number不能赋值给boolean updateSettings('language', 'FR'); // 错误:'FR'不属于'EN' | 'NL'
通用化扩展(适配任意对象)
如果需要一个通用的对象属性更新函数,可进一步泛化:
function updateObject<T, K extends keyof T>(obj: T, key: K, value: T[K]) { obj[key] = value; } // 使用示例 updateObject(settings, 'isOpen', false); updateObject(settings, 'width', 500);
这种方式既解决了never类型的赋值问题,又实现了严格的类型安全校验,完全符合需求。
内容的提问来源于stack exchange,提问作者Roy Prins
相关产品推荐
相关产品推荐

