如何在不使用$FlowFixMe的情况下为Immutable Record动态设置值
报错根本原因
Immutable Record 本质是固定键集合的结构,Flow 类型定义默认没有给它添加索引签名,当你使用动态字符串作为计算属性构建对象传入 merge 时,Flow 无法验证这个动态 key 是否属于当前 Record 的合法键,因此抛出索引签名缺失的错误。
可行解决方案(无需直接用$FlowFixMe跳过)
方案1:优先使用
set方法修改单字段(最优解)
你当前的场景只需要修改单个字段,完全可以替换merge为Record自带的set方法,同时把attr的类型约束为你定义的Record类型的键集合即可,示例代码:// 替换为你实际定义的FilterRecord类型 type FilterRecord = { showActive: boolean, showExpired: boolean, // 其他你声明的Record字段 } // 将attr的类型声明为FilterRecord的合法键集合 const attr = (event.target.value: $Keys<FilterRecord>); // 用set替代merge,Flow可以正常校验类型合法性 const query = filter.set(attr, !filter.get(attr));这种方式不需要任何特殊兼容处理,Flow可以完整校验类型合法性,不会丢失类型校验能力。
方案2:给merge的入参添加强类型断言
如果你确实需要使用merge(比如同时修改多个动态字段),可以给传入的对象断言为对应Record的Partial类型:const attr = (event.target.value: $Keys<FilterRecord>); const query = filter.merge({ [attr]: !filter[attr] } as Partial<FilterRecord>);方案3:为你的Record类型扩展索引签名(不推荐)
如果你的业务场景确实需要大量使用动态key操作Record,可以在定义Record类型的时候直接添加索引签名:type FilterRecord = { showActive: boolean, showExpired: boolean, [key: string]: boolean | string // 按你字段的实际类型定义 }这种方式会降低类型校验的严格程度,除非必要不建议使用。
补充说明
只有当以上方案都不适用你的特殊场景时,再考虑使用// $FlowFixMe跳过校验。你使用的v4.0.0-rc.14版本已经自带官方Flow类型定义,建议优先使用官方类型而非flow-typed社区贡献的旧版本定义,避免出现类型定义不匹配的问题。
内容的提问来源于stack exchange,提问作者DPA
相关产品推荐
相关产品推荐

