| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
|
TypeScript Bot (@typescript-bot) test this |
Sorry, something went wrong.
|
Heya Anders Hejlsberg (@ahejlsberg), I've started to run the parallelized Definitely Typed test suite on this PR at 015f4c5. You can monitor the build here. It should now contribute to this PR's status checks. |
Sorry, something went wrong.
|
Heya Anders Hejlsberg (@ahejlsberg), I've started to run the extended test suite on this PR at 015f4c5. You can monitor the build here. It should now contribute to this PR's status checks. |
Sorry, something went wrong.
|
RWC test run is clean. DT test run has one minor difference in ember/test/detect-instance.ts. Types such as null & { foo: string } and undefined & { foo: string } now reduce to never but previously would stick around (yet disappear in union types) and allow properties to be accessed. The new behavior is definitely more consistent. |
Sorry, something went wrong.
|
Does this still support branding via object literals? type Tag<T> = T & { readonly brand: unique symbol };
type TaggedNumber = Tag<number>; // not never |
Sorry, something went wrong.
|
Jack Williams (@jack-williams) It does, except you can't brand null or undefined. You sort of could before, but only in a limited sense. The minute you put null & { brand: xxx } in a union type it would disappear. |
Sorry, something went wrong.
|
Jack Williams (@jack-williams) The only thing that changes with this PR is when we reduce away empty intersections. We now do it upon construction but we used to do it only when an intersection was put in a union type. The actual patterns we reduce away (or don't reduce away) remain the same. |
Sorry, something went wrong.
Ah, that makes it clearer. Thank you! |
Sorry, something went wrong.
| if (type.flags & TypeFlags.Unit && includes & TypeFlags.Unit) { | ||
| // We have seen two distinct unit types which means we should reduce to an | ||
| // empty intersection. Adding TypeFlags.NonPrimitive causes that to happen. | ||
| includes |= TypeFlags.NonPrimitive; |
There was a problem hiding this comment.
Counterexample:
enum A {
Zero = 0,
One = 1
}
type Zeroish<T> = T & 0;
type ShouldNotBeNever = Zeroish<A.Zero> | never;we handle this incorrectly in master already - I'm just not a fan of propagating the logical error.
Sorry, something went wrong.
There was a problem hiding this comment.
So is the reason for that that the code highlighted considers A.Zero and 0 to be distinct? I'm just trying to ascertain where in that example above the never creeps in.
Sorry, something went wrong.
There was a problem hiding this comment.
Wesley Wigham (@weswigham) I think it is debatable whether we want to consider literals and literal enum members with the same underlying value to be intersectable. But either way, it is an issue that should be covered in a separate PR. Here we're just concerned with changing when we reduce, not how.
Sorry, something went wrong.
Sorry, something went wrong.
|
Heya Anders Hejlsberg (@ahejlsberg), I've started to run the parallelized Definitely Typed test suite on this PR at 015f4c5. You can monitor the build here. It should now contribute to this PR's status checks. |
Sorry, something went wrong.
|
RWC and DT test runs are both clean now. |
Sorry, something went wrong.
There was a problem hiding this comment.
I expect we'll get some reports about the using-an-enum-to-tag break upon release - we should remember to include this in the breaking change log.
Sorry, something went wrong.
|
Hi I wanted to check to see if this has already been resolved as I am still facing this issue. |
Sorry, something went wrong.
Utilizing [TypeScript intersection](microsoft/TypeScript#31838) to simplify config types. Config keys and payload can now always be `undefined`.
| Back | FazBrowse Home | New Git URL |
With this PR we reduce empty intersections to never immediately upon construction. For example, instead of preserving the type string & number and only reducing it away in union types we now immediately reduce it to never.
Some examples of types that now immediately reduce to never:
In #18438 we chose to preserve empty intersection types (a) to make it easier to understand how they originated and (b) to partially preserve the ability to "tag" primtive types using enum types (e.g. string & Tag where Tag is an enum). In practice this doesn't seem to outweigh the confusion these types bring about, in particular because there are subtle behavioral differences between never and types like string & number even though they really should be the same. The differences include:
These differences have no practical value. Particularly confusing is that string & boolean reduces to never (because it normalizes to string & true | string & false, which then reduces to never), whereas string & number sticks around and behaves differently.
Fixes #31663.