I'm trying to build a type that has a set of nested properties that will be extended by some method.
// this will what a "full built" meta should look like
type Meta = {|
foo: string,
bar: string
|}
// the full type "A" includes a full built meta
type A = {|
type: string,
meta: Meta
|}
// when creating a skinny vesion of A, we omit some attributes from meta
type NotPresentInSkinnyAMeta = {|
foo: string
|}
// so SkinnyA.meta is a diff between the full built meta and the properties that shouldn't be present
type SkinnyA = {|
type: string,
meta: $Diff<Meta, NotPresentInSkinnyAMeta>
|}
// all good here, works as expected
const skinny: SkinnyA = {
type: 'a',
meta: {
bar: 'b'
}
}
// throws "Cannot assign object literal to `notSkinny` because property `foo` is missing in `Meta` [1] but exists in `Meta` [2] in property `meta`."
const notSkinny: A = {
...skinny,
meta: {
...skinny.meta,
foo: 'b'
}
}
Simpler repro (without $Diff, type, or skinny):
// @flow
type Meta = {|
foo: string,
bar: string,
|};
type A = {|
meta: Meta
|};
const okay: A = {
meta: {bar: 'b'},
meta: {foo: 'a', bar: 'b'},
};
const notOkay: A = {
...{meta: {bar: 'b'}}, // errors, but shouldn't
meta: {foo: 'a', bar: 'b'},
};
While this definitely seems like a bug, it鈥檚 not a particularly
surprising one. The spread operator sees that the target has an
attribute with key meta and value {bar: 'b'}, which is inconsistent
with $PropertyType<A, "meta"> (namely, Meta), so it complains. It is
failing to take into account that this property is overridden later in
the object anyway. At least, it seems to me that this is what鈥檚
happening.
Related: #6498.
@Ricardo-Marques, that seems unrelated; the error persists if you
replace ...UnauthenticatedHeaders with Language: "en" | "es" to
inline the spread, and is more easily reproduced by
// @flow
const x: $Shape<{a: number} | {b: string}> = {a: 1};
Feel free to open a different thread.
This no longer errors in master
Most helpful comment
Simpler repro (without
$Diff,type, orskinny):While this definitely seems like a bug, it鈥檚 not a particularly
surprising one. The spread operator sees that the target has an
attribute with key
metaand value{bar: 'b'}, which is inconsistentwith
$PropertyType<A, "meta">(namely,Meta), so it complains. It isfailing to take into account that this property is overridden later in
the object anyway. At least, it seems to me that this is what鈥檚
happening.