-
Notifications
You must be signed in to change notification settings - Fork 13.2k
Description
🔎 Search Terms
generic function assignability, union return type, tuple union, TS2322, regression v4.2, generic type alias
🕗 Version & Regression Information
- This changed in commit 34f0e32 Bump version to 4.2.3 and LKG
- This also reproduces on Nightly version
⏯ Playground Link
💻 Code
type ReadA = <R>() => [false, R] | [true, R | undefined];
type ReadB = <R>() => [false, R] | [true, R | undefined];
// Error: Type 'ReadA' is not assignable to type 'ReadB'.
const test = (_: ReadA): ReadB => _;
// Also happens with object types
type ReadObjA = <R>() => { done: false; value: R } | { done: true; value: R | undefined };
type ReadObjB = <R>() => { done: false; value: R } | { done: true; value: R | undefined };
// Error: Type 'ReadObjA' is not assignable to type 'ReadObjB'.
const testObj = (_: ReadObjA): ReadObjB => _;🙁 Actual behavior
The code fails to compile with error TS2322: Type 'ReadA' is not assignable to type 'ReadB'.
It appears that the compiler incorrectly widens the generic type parameter R in the source type.
Although ReadA is defined as [false, R] | ..., the error message reports the source type as having [false, R | undefined].
It seems that during the generic signature assignability check, the undefined from the [true, R | undefined] branch is leaking into the inference of R for the entire union, causing the false branch to become [false, R | undefined]. This widened source type is then incompatible with the target's more strict [false, R] branch.
Type 'ReadA' is not assignable to type 'ReadB'.
Type '[true, R | undefined] | [false, R | undefined]' is not assignable to type '[false, R] | [true, R | undefined]'.
Type '[false, R | undefined]' is not assignable to type '[false, R] | [true, R | undefined]'.
Type '[false, R | undefined]' is not assignable to type '[false, R]'.
Type at position 1 in source is not compatible with type at position 1 in target.
Type 'R | undefined' is not assignable to type 'R'.
'R' could be instantiated with an arbitrary type which could be unrelated to 'R | undefined'.(2322)
Type 'ReadObjA' is not assignable to type 'ReadObjB'.
Type '{ done: false; value: R | undefined; } | { done: true; value: R | undefined; }' is not assignable to type '{ done: false; value: R; } | { done: true; value: R | undefined; }'.
Type '{ done: false; value: R | undefined; }' is not assignable to type '{ done: false; value: R; } | { done: true; value: R | undefined; }'.
Type '{ done: false; value: R | undefined; }' is not assignable to type '{ done: false; value: R; }'.
Types of property 'value' are incompatible.
Type 'R | undefined' is not assignable to type 'R'.
'R' could be instantiated with an arbitrary type which could be unrelated to 'R | undefined'.(2322)
🙂 Expected behavior
The code should compile without errors because ReadA and ReadB are structurally identical types.
Additional information about the issue
No response