TypeScript类型转换:类reset方法类型不兼容问题求解
解决TypeScript中
this[key] = true的类型不兼容问题 问题背景
你定义了这样一个控制列显示的类:
export class AccountApprovedColumnFilter { public showRowNumber: boolean = true; public showImage: boolean = true; public showProduct: boolean = true; public showCategory: boolean = true; public showGender: boolean = true; public showSupplyingAccount: boolean = true; public showSalesOrder: boolean = true; public showRequestedUnits: boolean = true; public showApprovedUnits: boolean = true; public showSizeDetails: boolean = true; public showSubmit: boolean = true; public reset(): void { for (let key in this) { if (this.hasOwnProperty(key)) { this[key] = true; // 这里触发类型错误 } } } }
Visual Studio抛出的错误提示是:
Type 'true' is not assignable to type 'this[keyof this]'.
原因分析
TypeScript的类型检查在这里比较严谨:keyof this会包含类中所有属性的键,虽然你当前所有属性都是boolean类型,但TypeScript无法确保未来不会添加非布尔值属性,所以它拒绝将true赋值给类型不确定的this[key]。
几种可行的解决方法
方法1:显式断言属性为布尔类型
直接给this[key]添加类型断言,明确告诉TypeScript你确定这个属性是布尔值:
public reset(): void { for (let key in this) { if (this.hasOwnProperty(key)) { (this[key] as boolean) = true; } } }
方法2:用Record约束类的属性类型
通过Record工具类型,给当前实例做一次类型转换,明确所有属性的类型都是boolean:
public reset(): void { const typedSelf = this as Record<keyof AccountApprovedColumnFilter, boolean>; for (let key in typedSelf) { if (typedSelf.hasOwnProperty(key)) { typedSelf[key] = true; } } }
方法3:遍历已知属性数组(推荐)
先手动列出所有属性名的数组,再遍历这个数组。这种方式既解决了类型问题,还能避免遍历到原型链上的属性,代码可读性也更强:
export class AccountApprovedColumnFilter { public showRowNumber: boolean = true; public showImage: boolean = true; public showProduct: boolean = true; public showCategory: boolean = true; public showGender: boolean = true; public showSupplyingAccount: boolean = true; public showSalesOrder: boolean = true; public showRequestedUnits: boolean = true; public showApprovedUnits: boolean = true; public showSizeDetails: boolean = true; public showSubmit: boolean = true; // 提前定义所有需要重置的属性键 private readonly columnKeys: Array<keyof AccountApprovedColumnFilter> = [ 'showRowNumber', 'showImage', 'showProduct', 'showCategory', 'showGender', 'showSupplyingAccount', 'showSalesOrder', 'showRequestedUnits', 'showApprovedUnits', 'showSizeDetails', 'showSubmit' ]; public reset(): void { this.columnKeys.forEach(key => { this[key] = true; }); } }
内容的提问来源于stack exchange,提问作者Willem de Jong
相关产品推荐
相关产品推荐

