You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Generic function type inference unnecessarily narrow in the case of two Generic bind sites, (object keys and array members) creating an unexpected error.
🔎 Search Terms
Generic function type narrow
🕗 Version & Regression Information
This is the behavior in every version I tried, and I reviewed the FAQ for entries about Generic inference and binding
typeWide="vanilla"|"chocolate"|"raspberry";typeLookup<NarrowextendsWide>={[kinNarrow]: boolean;};functionflag<NarrowextendsWide>(lookup: Lookup<Narrow>,
...items: [Narrow, ...Narrow[]]){for(constitemofitems){lookup[item]=true;}}flag({vanilla: false,chocolate: true,// this line is unexpectedly an error},"vanilla");
🙁 Actual behavior
The Narrow type in the call to flag is inferred only as "vanilla" (apparently taking account only of items and not inferring from lookup).
This causes the "chocolate" property in the lookup to be incorrectly flagged as an error, when the "chocolate" property should actually have caused the Narrow type to be broadened to include "chocolate".
This remains true if as const or a const Generic type is used for the lookup.
It's only if every single entry of keyof lookup is listed in items that the compiler errors go away, which is surprising, as the definition of items should allow one or more of the keys of lookup, but not necessarily all of them.
🙂 Expected behavior
A Narrow type of "vanilla" | "chocolate" should have been inferred from the lookup argument to the flag call. The type inferred from the lookup is a superset of the type inferred from the items therefore this should have been used instead, hence eliminating a spurious error.
The text was updated successfully, but these errors were encountered:
This is working as intended. The inferences we make from the top-level occurrences of the type parameter in the rest argument list are considered better inferences than those we make from the mapped type.
Ideally you want to indicate that no inferences should be made from the rest arguments, so this is effectively another request for #14829. However, the suggested workaround for that issue actually applies here:
typeWide="vanilla"|"chocolate"|"raspberry";functionflag<TextendsWide,UextendsT>(lookup: Record<T,boolean>, ...items: [U, ...U[]]){for(constitemofitems){lookup[item]=true;}}flag({vanilla: false,chocolate: true},"vanilla");// Ok
Bug Report
Generic function type inference unnecessarily narrow in the case of two Generic bind sites, (object keys and array members) creating an unexpected error.
🔎 Search Terms
Generic function type narrow
🕗 Version & Regression Information
⏯ Playground Link
Playground link with relevant code
💻 Code
🙁 Actual behavior
The
Narrow
type in the call toflag
is inferred only as"vanilla"
(apparently taking account only ofitems
and not inferring fromlookup
).This causes the
"chocolate"
property in thelookup
to be incorrectly flagged as an error, when the"chocolate"
property should actually have caused theNarrow
type to be broadened to include"chocolate"
.This remains true if
as const
or aconst
Generic type is used for thelookup
.It's only if every single entry of
keyof lookup
is listed initems
that the compiler errors go away, which is surprising, as the definition ofitems
should allow one or more of the keys oflookup
, but not necessarily all of them.🙂 Expected behavior
A
Narrow
type of"vanilla" | "chocolate"
should have been inferred from thelookup
argument to the flag call. The type inferred from thelookup
is a superset of the type inferred from theitems
therefore this should have been used instead, hence eliminating a spurious error.The text was updated successfully, but these errors were encountered: