使用reduce创建字典时遭遇Flow错误:对象字面量缺失属性
问题:使用reduce创建字典时Flow报错“object literal中缺少属性”
我想用reduce方法从数组生成字典,但Flow报错“object literal中缺少属性”,涉及'A'、'B'、'C'三个键。代码示例如下:
const foo = [ 'A', 'B', 'C', ]; const bar = foo.reduce((acc, curr) => { // 实际代码会对数组中的字符串做一些逻辑处理 // 测试阶段先创建一个键值相同的字典 acc[curr] = curr; return acc; }, {});
解决方法
1. 给初始值添加字典类型注解
Flow默认把{}推断为空对象类型,不允许添加新属性。直接给初始值指定字典类型即可:
const bar = foo.reduce((acc, curr) => { acc[curr] = curr; return acc; }, {} as {[key: string]: string});
2. 定义精确的类型别名
如果明确知道字典的键是固定的'A'、'B'、'C',可以定义更精确的类型:
// 如果确定所有键最终都会存在,使用必选属性 type FixedDict = { A: string, B: string, C: string, }; // 如果reduce过程中属性是逐步添加的,先定义可选属性 // type FixedDict = { // A?: string, // B?: string, // C?: string, // }; const bar = foo.reduce((acc, curr) => { acc[curr] = curr; return acc; }, {} as FixedDict);
3. 使用$Shape工具类型(适用于逐步填充完整字典的场景)
如果最终要得到一个包含所有固定键的字典,但reduce过程中是逐步添加的,可以用$Shape来允许初始值缺少部分属性:
type FullDict = { A: string, B: string, C: string, }; const bar = foo.reduce((acc, curr) => { acc[curr] = curr; return acc; }, {} as $Shape<FullDict>);
原因说明
Flow对空对象的类型推断非常严格,默认{}的类型是没有任何属性的空对象,因此当你尝试往里面添加属性时,Flow会认为你违反了类型约定,抛出“缺少属性”的错误。通过显式指定类型,告诉Flow这个对象是可以包含指定键值对的字典,就能解决问题。
内容的提问来源于stack exchange,提问作者Jay Hu
相关产品推荐
相关产品推荐

