使用as keyof interface转换字符串为键时,readonly属性引发错误如何解决?
解决TypeScript readonly属性赋值错误问题
问题根源
TypeScript的静态类型检查不会通过运行时的if判断自动缩小参数类型范围——哪怕你写了fieldname != "id",它依然认为fieldname有可能是'id',因此会触发"无法赋值给只读属性'id'"的错误。
最优解决方案:从参数类型层面限制
直接修改fieldname的类型,明确排除'id',这样不仅能在编译期拦截非法参数,还能去掉冗余的运行时判断:
updateField(tenantId: string, fieldname: Exclude<keyof Tenant, 'id'>, value: string | number | boolean | Array<SubTenant> | undefined) { const tenantPartial = {} as Partial<Tenant>; tenantPartial[fieldname] = value as any; this.buildingService.updateTenantField(this.buildingId, tenantId, tenantPartial); }
说明:Exclude<keyof Tenant, 'id'>会生成Tenant接口中除'id'外的所有键的联合类型(这里就是'name'),确保传入的fieldname只能是可修改的字段。
兼容旧调用的解决方案(保留fieldname为string类型)
如果无法修改fieldname的参数类型(比如外部调用传入的是string),可以在赋值时通过类型断言告诉TypeScript当前fieldname不是'id':
updateField(tenantId: string, fieldname: string, value: string | number | boolean | Array<SubTenant> | undefined) { const tenantPartial = {} as Partial<Tenant>; if (fieldname !== "id") { // 断言fieldname为排除'id'后的合法键 tenantPartial[fieldname as Exclude<keyof Tenant, 'id'>] = value as any; } this.buildingService.updateTenantField(this.buildingId, tenantId, tenantPartial); }
内容的提问来源于stack exchange,提问作者Jon Thompson
相关产品推荐
相关产品推荐

