Open
Description
π Search Terms
"return type destructure"
"destructuring assignment type"
π Version & Regression Information
- This changed between versions 3.3.3 and 3.5.1
β― Playground Link
π» Code
type R = {
A: {
a: 'A'
} | null | undefined
}
function fn<T extends R>(t:T): T {
return {} as T;
}
/*
In each test case below, I'd assume the return type of function to be `{A: {a: 'A'}}`.
However, case 4 uses destructuring and this appears to default the return type to `R`.
*/
// Case 1
// Correctly infers type of `result.A` as `{A: {a: 'A'}}`
const result = fn({A: {a: 'A'}});
result.A.a; // No error
// Case 2
// Correctly infers type of A1 as `{a: 'A'}`
const A1 = fn({A: {a: 'A'}}).A;
A1.a; // No error
// Case 3
// Correctly infers type of A3 as `{a: 'A'}`
const {A: A2} = fn({A: {a: 'A'}} as const);
A2.a; // No error
// Case 4
// Incorrectly infers type of A2 as `{A: {a: 'A'} | null | undefined}`
const {A: A3} = fn({A: {a: 'A'}});
A3.a; // Error: Object is possibly `null` or `undefined`
π Actual behavior
In case 4, accessing A3.a
results in error "Object is possibly null
or undefined
".
Appears that the inferred type of A3
is {a: 'A'} | null | undefined
. I suspect when we destructure, the return type of fn
is inferred as R
instead of the narrowed generic type variable T
.
π Expected behavior
Expect no errors. Should be able to access A3.a
, similar cases 1, 2, and 3. Expectation is that destructuring assignment shouldn't modify inferred return type of function.
Additional information about the issue
Current workarounds:
- Use
as const
appended to param (see case 3) - Use
const
with generic type variable in function signature (function fn<const T extends R>(t: T): T;
) - Avoid destructuring assignments (case 1 & 2)