Description
Bug Report
🔎 Search Terms
extract assignable TS2322
🕗 Version & Regression Information
This is the behavior in every version I tried, and I reviewed the FAQ for entries about Generics, Assignability, and Extract.
Tested with 4.2.3, 4.3.5, 4.4.4, and 4.5.0-dev.20211018.
In 4.1.5, the example using a type alias also fails. Version 4.2 introduced Smarter Type Alias Preservation, which may explain why that example passes starting from 4.2.x.
⏯ Playground Link
Playground link with relevant code
💻 Code
I have attempted to minimize this example as much as possible. The use of Extract
to define a field type appears to be significant.
type A<T> = {
val: Extract<number | string, T>;
};
type A_number = A<number>;
function f1(x: A_number): A<number| string> {
// Passes type checking.
return x;
}
function f2(x: A<number>): A<number | string> {
// Fails type checking with error TS2322:
// Type 'A<number>' is not assignable to type 'A<string | number>'.
// Type 'string | number' is not assignable to type 'number'.
// Type 'string' is not assignable to type 'number'.
return x;
}
🙁 Actual behavior
The type checker reports error TS2322: A<number>
is not assignable to type A<string | number>
because string | number
is not assignable to number
. It appears to be checking assignability of a field in the wrong direction, because the assignability check should be whether number
is assignable to string | number
.
Using a type alias for A<number>
does not produce the same error. I was also not able to reproduce this error without using Extract
to define a field type.
🙂 Expected behavior
The type A<number>
should be assignable to type A<string | number>
because it is a simple object type and number
is assignable to string | number
.