TypeScript动态赋值对象字面量时类型错误的问题问询
TypeScript类型错误排查与修复
我已经花了数小时,仍无法定位这个TypeScript错误的原因。因无法展示真实代码,现将问题简化为以下示例代码:
abstract class CustomerType { protected abstract customerInfo?: IUserInfo; } enum CustomerGroup { FirstTimer = "first timer", Subscriber = "subscriber" } interface IUserInfo { group?: CustomerGroup; firstClassMember?: boolean; rewardsMember?: boolean; } abstract class CustomerType { protected abstract customerInfo?: IUserInfo; } class Default extends CustomerType { protected customerInfo: IUserInfo = {}; constructor(){ super(); } get _customerInfo(){ return this.customerInfo ?? {} } set _customerInfo(customerInput: IUserInfo){ let input: keyof IUserInfo; for(input in customerInput){ if(customerInput[input] === undefined) continue; this.customerInfo = customerInput[input]; } } }
错误信息
类型“boolean | CustomerGroup | undefined”无法分配给类型“IUserInfo”。类型“undefined”无法分配给类型“IUserInfo”。(2322)
尽管错误上方已做检查,TypeScript仍无法推断customerInput[input]不为undefined。
问题分析与修复
这里的错误有两个核心原因:
- 逻辑错误:你试图将
customerInput的单个属性值(类型为boolean | CustomerGroup)直接赋值给this.customerInfo(类型为IUserInfo对象),类型完全不匹配。正确逻辑应该是将对应属性的值赋值给this.customerInfo的同名属性,而非替换整个对象。 - 类型收窄限制:TypeScript在
for...in循环中无法自动推断customerInput[input]的类型已排除undefined,需要手动辅助类型收窄。
修正后的代码
abstract class CustomerType { protected abstract customerInfo?: IUserInfo; } enum CustomerGroup { FirstTimer = "first timer", Subscriber = "subscriber" } interface IUserInfo { group?: CustomerGroup; firstClassMember?: boolean; rewardsMember?: boolean; } abstract class CustomerType { protected abstract customerInfo?: IUserInfo; } class Default extends CustomerType { protected customerInfo: IUserInfo = {}; constructor(){ super(); } get _customerInfo(){ return this.customerInfo ?? {} } set _customerInfo(customerInput: IUserInfo){ let input: keyof IUserInfo; for(input in customerInput){ const value = customerInput[input]; if(value === undefined) continue; // 赋值给对应属性,而非替换整个对象 // 手动收窄类型,排除undefined this.customerInfo[input] = value as Exclude<IUserInfo[keyof IUserInfo], undefined>; } } }
关键修改说明
- 把
this.customerInfo = customerInput[input]改为this.customerInfo[input] = value,修正逻辑错误,确保是给对象的单个属性赋值,而非替换整个对象。 - 通过
as Exclude<IUserInfo[keyof IUserInfo], undefined>手动收窄类型,告诉TypeScript此时的value已经排除了undefined,解决类型推断问题。 - 将
customerInput[input]赋值给临时变量value,让类型检查更清晰。
内容的提问来源于stack exchange,提问作者Daryl
相关产品推荐
相关产品推荐

