-
Notifications
You must be signed in to change notification settings - Fork 12.8k
2.9 and 3.0 reduce type of optional branded string member as undefined #25709
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This is working as intended and is the same issue as #24846. The compiler now removes empty intersection when they occur in union types. An empty intersection type is a type that is known to have zero possible values. Examples include Since an enum is a subtype of Generally the recommended way to create branded types is to intersect with an object type: type BrandedString = string & { __brand__: void }; |
Aha! Well, reducing empty intersection types to never certainly makes a lot of sense. I love it – intersecting enums always seemed like hack. However, the way in which that manifests today is pretty confusing, because you only get feedback about the issue in certain circumstances, sometimes far removed from the definition of the original type. (In our case it was a It seems that if an empty intersection is effectively the same as never, it should effectively be the same as never everywhere. There are probably reasons I'm not appreciating for not reducing invalid intersections to never right away, but the property of having an intersection behave uniformly does seem really appealing. If TypeScript had reported my intersection type to be With the current behavior, user-defined intersection types seem to work just fine until you happen to want to e.g. use them for an optional property. Hovering shows the type definition, non-unioned uses work as they used to, and only in some circumstances do they behave in a matter inconsistent with every other type I've written. But assuming there's more to the story than meets the eye, it would have been nice to have had some sort of hint that there was an issue with my branded type. Either a warning or even just a note in the tooltip for the type would have helped clarify the situation for me. Thanks for the quick reply and the excellent work! |
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed. |
TypeScript Version: 3.0.0-dev.20180712, 3.0-rc, 2.9. Our original code worked fine in 2.8 with
strictNullChecks
enabled.Search Terms: strictNullChecks, branding, enum, optional, intersection, undefined
Code
Expected behavior: Example type checks
Actual behavior: Example does not type check TypeScript thinks
optional
is has typeundefined
.Playground Link: Ensure strictNullChecks is enabled. Link here
Related Issues: #25179 looks similarish
The text was updated successfully, but these errors were encountered: