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
{{ message }}
Repository navigation
Non-null assertion doesn't work for mapped types #23849
Actual behavior:
In 2.7.2:
error TS2322: Type '{ [key in A]: {} | undefined; }[A]' is not assignable to type '{}'.
Type '{} | undefined' is not assignable to type '{}'.
Type 'undefined' is not assignable to type '{}'.
In 2.9.0-dev.20180502:
error TS2322: Type 'NonNullable<{ [key in A]: {} | undefined; }[A]>' is not assignable to type '{}'.
Type '{} | undefined' is not assignable to type '{}'.
Type 'undefined' is not assignable to type '{}'.
Playground Link:
I cannot reproduce the error in the playground.
From command line, I'm running node_modules/.bin/tsc -strict test.ts to reproduce it.
I'm going to guess that when we look at NonNullable<{ [key in A]: {} | undefined; }[A]> and instantiate with the constraint and simplify to NonNullable<{} | undefined>, the process through which we do so is not creating a distributive conditional type (the original conditional was not distributed, and {} | undefined doesn't extend undefined, so just passes thru unchanged).
Bowen Ni (@bowenni) because as it turns out, this is a regression introduced by #23592, I believe (since, looking at the playground, it clearly worked in 2.8).
Update: Our conditional type constraint comparison logic was incorrect, but not for the stated reason. The distributivity is handled correctly, but how we got the constraint for an indexed access is off. We saw {[K in A]: {} | undefined}[string] and just...decided not to simplify it and return no constraint because the object type was generic.
Activity
mhegazy commentedon May 3, 2018
Wesley Wigham (@weswigham) can you take a look.
weswigham commentedon May 3, 2018
I'm going to guess that when we look at
NonNullable<{ [key in A]: {} | undefined; }[A]>and instantiate with the constraint and simplify toNonNullable<{} | undefined>, the process through which we do so is not creating a distributive conditional type (the original conditional was not distributed, and{} | undefineddoesn't extendundefined, so just passes thru unchanged).bowenni commentedon May 3, 2018
Another question is why this is irreproducible in the playground?
weswigham commentedon May 3, 2018
Bowen Ni (@bowenni) because as it turns out, this is a regression introduced by #23592, I believe (since, looking at the playground, it clearly worked in 2.8).
Update: Our conditional type constraint comparison logic was incorrect, but not for the stated reason. The distributivity is handled correctly, but how we got the constraint for an indexed access is off. We saw
{[K in A]: {} | undefined}[string]and just...decided not to simplify it and return no constraint because the object type was generic.bowenni commentedon May 3, 2018
Thank you Wesley for the explanation!
weswigham commentedon May 4, 2018
And I've got a fix up at #23884 😉