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
Inference to unions containing void behave differently from 4.2 on #42786
functionisDefined<T>(value: T|undefined|null|void): value is T{returnvalue!==undefined&&value!==null;}declareconstfoo: string|undefined;if(isDefined(foo)){// 4.2: foo is string | undefined// 4.1: foo is stringconsole.log(foo.toUpperCase());}
changed the title [-]Unions containing `void` behave differently from 4.2 on[/-][+]Inference to unions containing `void` behave differently from 4.2 on[/+]on Feb 13, 2021
Likely involves the changes from #42353, and I have theories of what we probably do, but Anders Hejlsberg (@ahejlsberg) will surely have a better idea.
Yeah, this one is an effect of us now reducing void | undefined to just void. With that reduction, the type of the value parameter becomes T | null | void, but then the value !== undefined test in the body doesn't remove void because we sometimes think of void possibly being any type. So, we're trying to have our cake and eat it too, and it isn't working.
We've had many discussions about our strange void semantics, but we have yet to come up with something better that doesn't break the world. However, in the spirit of at least not breaking things, we could dial back and only do the void | undefined to void reduction in cases where we perform subtype reduction. That was our previous behavior.
Reacted by Karol Majewski, Raffael Campos, SancheZz and Ryan Cavanaugh
is that an option? Is it just a matter of special-casing how we invoke literal type reduction?
Yes, it's an option and it isn't particularly hard to implement. We'd just make the void | undefined to void reduction in the literal type reduction pass conditional on whether we are also (in a subsequent pass) performing subtype reduction.
Activity
[-]Unions containing `void` behave differently from 4.2 on[/-][+]Inference to unions containing `void` behave differently from 4.2 on[/+]DanielRosenwasser commentedon Feb 13, 2021
Likely involves the changes from #42353, and I have theories of what we probably do, but Anders Hejlsberg (@ahejlsberg) will surely have a better idea.
ahejlsberg commentedon Feb 15, 2021
Yeah, this one is an effect of us now reducing
void | undefinedto justvoid. With that reduction, the type of thevalueparameter becomesT | null | void, but then thevalue !== undefinedtest in the body doesn't removevoidbecause we sometimes think ofvoidpossibly being any type. So, we're trying to have our cake and eat it too, and it isn't working.We've had many discussions about our strange
voidsemantics, but we have yet to come up with something better that doesn't break the world. However, in the spirit of at least not breaking things, we could dial back and only do thevoid | undefinedtovoidreduction in cases where we perform subtype reduction. That was our previous behavior.DanielRosenwasser commentedon Feb 17, 2021
Anders Hejlsberg (@ahejlsberg) is that an option? Is it just a matter of special-casing how we invoke literal type reduction? That might be worth it.
ahejlsberg commentedon Feb 17, 2021
Yes, it's an option and it isn't particularly hard to implement. We'd just make the
void | undefinedtovoidreduction in the literal type reduction pass conditional on whether we are also (in a subsequent pass) performing subtype reduction.