Description
Reduce vacuous intersections
-
When we talk about unions and intersections we are talking about domains - sets which contain a number of values.
-
Specifically, when you have an intersection, you have a type that describes values that occupy each constituent of the intersection.
-
However, for certain sets of types that are completely disjoint, you have a completely empty domain of values.
-
And the type that describes the set of no values is simply
never
. -
So for certain types (e.g.
number & string
or"foo" & "bar"
), it makes sense to collapse them down tonever
. -
There's some strange behavior that might come about from this:
var s: string; var x: string & number; // does the quick info here become 'never'? The user didn't write that. var b: boolean = x; // you can also assign to anything all of a sudden // even though 'string & number' doesn't contain 'boolean'
-
We also get quite large slowdowns - @weswigham's experimental branch of discriminated union nodes takes minutes to compile.
-
So maybe we don't want to go all the way there. But for unit types, we certainly care.
-
Current behavior in the compiler:
type ABC = "A" | "B" | "C"; type BCD = "B" | "C" | "D"; type X = ABC & BCD; // Becomes... // | "B" | "C" | ("A" & "D") | ("A" & "B") | // | ("A" & "C") | ("B" & "D") | ("B" & "C") // | ("C" & "D") | ("C" & "B")
-
What about objects with properties that collapse to
never
?- Technically,
Circle & Square
(where each has a discriminated unit-typed property) should becomenever
since thekind
ortype
or whatever discriminating field will becomenever
as well.- Problem is that turning this into
never
becomes sort of opaque - no clue to the user how they got there. - Also can't diagnose the properties, though arguably you should be able to get properties off of a value of type
never
.
- Problem is that turning this into
- Technically,
-
Idea: current implementation just removes these vacuous unit intersection types when constructing unions.
- Means they'll get removed from explicit unions, but you can have a single intersection (outside of a union) that is a vacuous intersection of ujnit types.
-
Related issue: Reduce empty intersections to never #18210
- Maybe revisit next week.
- Current idea is stitching nullability back on after the fact.
Export assignment
-
What do you think this code does?
declare module "*.vue" { import Vue from 'vue' export default typeof Vue }
-
You're probably wrong.
-
A: ˙ǝdʎʇ ,ƃuᴉɹʇs, ǝɥʇ s,ʇI
-
Ideas
- We should disallow expressions in ambient contexts.
- Or ensure these ambiguous entities are parsed appropriately.
-
What about
export default class
?- Will be different,
default
is treated as a modifier here?
- Will be different,
Revision to tagged template string emit
- We originally opted into a simple implementation
- the simplest solution was to recreate the array
- leaves the code clean
- frameworks like lit-html take a dependency on the identity of the template, obviously our current behavior beaks them
emit options:
-
cache globally to match the current spec
- the spec is actually going to change, there is an issue on TC39 to only make that unique per template
-
defer the use until
-
what about variable names, could collide in cases of global scripts
- in global scripts, revert back to old behavior
- this would be confusing to users to have different semantics based on the context
- is not that the same as destructuring?
- destructuring only uses the variable for a short while during initialization, but templates has higher chance of conflicts
- make names unique, either use some hash of the contents, or the template location
- @DanielRosenwasser to figure this one out.
- in global scripts, revert back to old behavior
Merge contextual types from overloads
- Currently if a function is contextually typed by a type with multiple signatures (e.g. overloads), we "give up" and go to 'any'.
- Comes up in JSX where
props
has a specificrefs
type or when another type extends another component.
- Comes up in JSX where
Out of time