对象类型的Flowtype数组不允许额外的属性

Bal*_*ard 5 javascript flowtype

流程有一个奇怪的错误.我只是想尝试一个接受带有amount属性的对象数组的函数,但是在提供具有更多属性的对象时我遇到了错误.

const sum = (items: Array<{amount: number}>) => {/* something */}

type Item = {
  amount: number,
  name: string
};

const list: Array<Item> = [];

sum(list);
Run Code Online (Sandbox Code Playgroud)

这给了我以下错误:

10: const list: Array<Item> = [];
                      ^ property `name`. Property not found in
2: const sum = (items: Array<{amount: number}>) => {/* something */}
                             ^ object type
Run Code Online (Sandbox Code Playgroud)

https://flow.org/try/#0FAYw9gdgzgLgBFArgWzgXjgCgJYwKbJQBccAggE7kCGAngDwDeVyYiEMJEKARnuQL4A+AJTpBcBgHoAVAjDI8MABbYIAczjTJ-YLpg0ADnjgBJfKgwNgcOM1btOPPgBprcCMzwlY5VWuD8ANy64NDwADbYsCQU1PRmBOIYANoAusHASMiYkbDCgUA

log*_*yth 6

与此处描述的问题类似:https://github.com/facebook/flow/issues/1644

这是不允许的,因为你有声明,

const sum = (items: Array<{amount: number}>) => {/* something */}
Run Code Online (Sandbox Code Playgroud)

会允许的

const sum = (items: Array<{amount: number}>) => {
    items.push({amount: 4});
};
Run Code Online (Sandbox Code Playgroud)

鉴于声明,这是完全有效的items.传递给的数组sum是您的Item类型列表,需要一个name,这里没有设置.

正如您所提到的,$ReadOnlyArray有效,因为它是只读的,不能添加更多项目.或者,您可以sum完全删除类型定义,让Flow推断它们,或者更改Array<{amount: number}>为,Array<*>因此Flow知道它是一个数组,但会推断内容的类型.另一种选择(你在评论中留下的)是

const sum = <T : {amount: number}>(items: Array<T>) => {/* something */}
Run Code Online (Sandbox Code Playgroud)

它将设置TItem基于您的调用sum(list),限制它将接受任何T具有数字amount属性的对象.

这可能是最好的选择.