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 doesn't find common base type for union with null or undefined - TypeScript 4.8 regressionΒ #49938
functionequal<T>(a: T,b: T){}letv=null!;// Object types with common base typestypeB={foo: string}typeD={foo: string;bar: number}// Error in 4.8 TS can't find common type β// 4.7 T was undefined | Bequal(vasB,vasundefined|D)// ok T is B β equal(vasB,vasD)// ok T is B | undefined β equal(vasB,vasB|undefined)
π Actual behavior
In 4.8 TypeScript can't find common base type between B and undefined | D. In 4.7 this used to be B | undefined.
This also happens for literal types and their respective base types as well as for arrays as shown in the 'Other Examples' in the playground link. I didn't include the code as the bug is the same, it's just different instances we found in our code.
π Expected behavior
Typescript finds the type B | undefined for T as it did in 4.7.
Also interestingly, if you write equal(v as D | undefined, v as B) (so, flip the argument order), T is inferred as D | undefined.
I'm a little confused as to why the argument order matters here, but given that the inference if you swap the arguments is the same in 4.7, it's nothing new.
This part of the code doesn't consider the fact that any of the types could be unions that contain null or undefined, only types which are exactly null or undefined. I have a fix which correctly retains null and undefined which fixes this issue but doesn't make things consistent in argument order (so, same as 4.7). Currently verifying that this is right and that I can't also fix the other case too, since it seems incongruent with other inferences.
Activity
dragomirtitian commentedon Jul 18, 2022
Also reported in Bloomberg feedback #49835
jakebailey commentedon Jul 19, 2022
This also bisects to #49119.
jakebailey commentedon Jul 20, 2022
Also interestingly, if you write
equal(v as D | undefined, v as B)(so, flip the argument order),Tis inferred asD | undefined.I'm a little confused as to why the argument order matters here, but given that the inference if you swap the arguments is the same in 4.7, it's nothing new.
Playground Link
jakebailey commentedon Jul 20, 2022
I pinned this down to this part of the PR: https://github.com/microsoft/TypeScript/pull/49119/files#diff-d9ab6589e714c71e657f601cf30ff51dfc607fc98419bf72e04f6b0fa92cc4b8R21147
This part of the code doesn't consider the fact that any of the types could be unions that contain
nullorundefined, only types which are exactlynullorundefined. I have a fix which correctly retainsnullandundefinedwhich fixes this issue but doesn't make things consistent in argument order (so, same as 4.7). Currently verifying that this is right and that I can't also fix the other case too, since it seems incongruent with other inferences.jakebailey commentedon Jul 21, 2022
My fix doesn't seem to be the right one; we should probably discuss the intended inference behavior here.
EDIT: Well, maybe it is, after fixing a few things: Playground Link
ahejlsberg commentedon Jul 24, 2022
Fixed by #50021.