Description
Concerns with TypeScript 4.5's Node 12+ ESM Support
- Really only the last option - can't fix everything, clearly other things that need fixing.
- We don't know what we're going to find when the community actually does start to use it and "do it right".
- Only way we can get feedback is to make it easily accessible.
- Needs to ship under some experimental form - should it be enabled in 4.5?
- Feel okay with erroring with "This feature is only available in the nightly builds."
- In between the state now and the state when it's production ready, we think it's likely code will break.
- Could ship with an experimental name in 4.5, but unclear who we're helping with that mode.
- Bugs might be fixable in the next 2 weeks, ecosystem is more concerning.
- UX can be fixed over time.
- People who used an
exports
field didn't do it wrong, we're making it wrong under this system.
- Cons
- Open questions:
- Rename the flag?
- Less reason to rename under nightly-only.
- Leave the name as-is, add a diagnostic on program construction, you'll see it in the command line, but not under stuff like
transpileModule
.
- Rename the flag?
- What about
.mts
/.mjs
/.cts
/.cjs
?- What does it mean to use these outside of these module modes?
- Baseline support works for now; should be fine.
- What is the messaging?
- Stays in the 4.5 RC and Stable post.
- Explain why we made the decision, and what the min. criteria we have to help users move forward.
- Don't keep entire blog post?
- Still need something!
- Conclusions:
- Gate on nightly-only.
- Create an issue to issue an error when you use this in a stable release.
Simplifying Type Relationships with Target Conditonal Types
-
Added functionality to check that a type is always assignable to a conditional if it's assignable to both branches of the conditional.
-
Ideally, conditional types just go away when you can be sure the left & right sides of the
extends
are known to be assignable. -
Not the case, because of the fact that conditional types are also distributive.
type Foo<T> = T extends T ? Box<T> : never; // not the same as type Foo<T> = Box<T>; // for type Yadda = Foo<string | number>;
- We say don't try to resolve the conditional type if there are generics on any side.
-
So that PR had to do work to specially handle
infer
type parameters and distributive types.- The distributivity checks
-
When reasoning about type relationships, maybe we shouldn't try to do any further resolution.
-
Proposed change (Simplify relationship check for conditional type on target side #46429) is to avoid doing so; just do a plain check on non-distributive types to see if a source type is assignable to the target conditional's true and false branches.
-
One point was "if we can't do things eagerly, we shouldn't try to figure it out late"
- Not true! e.g.
keyof
is deferred. - Sometimes these are costly, sometimes they're not.
- Not true! e.g.
-
We've been adding more and more union/intersection property rules as well. That's exacerbated this.
- Have some ideas to make these faster too.
-
Could still hit the same issues if you replace these conditionals with union types.
-
Aside: current PR can't work in cases where the conditional is distributive; not sufficient to only check true/false branches when there are no
infer
type variables.