问题
I am having a strange error with flow.
I'm simply trying to have a function that accepts an array of objects with an amount
property but I'm having errors when providing objects with more properties.
const sum = (items: Array<{amount: number}>) => {/* something */}
type Item = {
amount: number,
name: string
};
const list: Array<Item> = [];
sum(list);
This gives me the following errors:
10: const list: Array<Item> = [];
^ property `name`. Property not found in
2: const sum = (items: Array<{amount: number}>) => {/* something */}
^ object type
https://flow.org/try/#0FAYw9gdgzgLgBFArgWzgXjgCgJYwKbJQBccAggE7kCGAngDwDeVyYiEMJEKARnuQL4A+AJTpBcBgHoAVAjDI8MABbYIAczjTJ-YLpg0ADnjgBJfKgwNgcOM1btOPPgBprcCMzwlY5VWuD8ANy64NDwADbYsCQU1PRmBOIYANoAusHASMiYkbDCgUA
回答1:
Similar to the issue described here: https://github.com/facebook/flow/issues/1644
This is not allowed, because the declaration you have,
const sum = (items: Array<{amount: number}>) => {/* something */}
would allow
const sum = (items: Array<{amount: number}>) => {
items.push({amount: 4});
};
which is totally valid given the declaration of items
. The array passed to sum
is a list of your Item
type, which requires a name
, which isn't set here.
As you mentioned, $ReadOnlyArray
works, because it is read-only and can't have more items added to it. Alternatively you could drop the type definitions from sum
entirely and let Flow infer them, or change Array<{amount: number}>
to Array<*>
so Flow knows it is an array, but will infer the type of the content. Another alternative (that you left in the comments) is
const sum = <T : {amount: number}>(items: Array<T>) => {/* something */}
which will set T
to Item
based on your call to sum(list)
, with the restriction that it will accept any T
that is an object with a numeric amount
property.
This is probably the best option.
来源:https://stackoverflow.com/questions/44155934/flowtype-array-of-object-type-does-not-allow-extra-properties