Closed
Description
- Intersection state Consistently propagate
intersectionState
in relations #52392- Unifies the interaction of excess property checking and weak types
- Key logic is in
structuredTypeRelatedTo
, dealing with properties which are nested in the intersection, e.g.{ a: { x: string } } & { c: number }
, we need to deal with both the intersection type and its final form- Contrast with something like
{ a: { x: string } } & { a: { y: number } }
- a contextual-agnostic analyis can't handle this correctly - Interacts with
isDeeplyNestedType
, which exists to prevent runaway stackoverflows in generatively-recursive types- The "identity key" here is, for example, the
symbol
of a declared type - For intersections, no such durable/reusable identity key existed
- This meant we couldn't safely plumb to more than a fixed depth (1) of intersections when looking for excess properties
- The "identity key" here is, for example, the
- Fix: Instead, an intersection is deeply nested if any of its constituents is deeply nested
- Now we don't need a fixed depth limit
- Fix is good, everything's passing
- Check time for
vuelidate
on DT has doubled, but really only because we're doing work we should have been doing the whole time - 5.0 or 5.1?
- It's a bugfix, standard level of riskiness, 5.0.
- Widening/nonwidening enum literals Widening and non-widening computed enum types #52542
- In 5.0 we unified
enum
logic, yay - Consider
enum E { A = 1, B = 2, C = 3}
- Type
E
is a union,E.A | E.B | E.C
- Type
- Contrast
enum X { A = compute(0), B = compute(1), C = compute(2) }
- Old behavior: type
X
is justX
, a subtype ofnumber
- New behavior: type
X
is a union ofX.A | X.B | X.C
, pretty much the same asE
, each of which is an opaque subtype of number
- Old behavior: type
- All motivating scenarios that led to fresh/nonfresh widening/nonwidening literal types for string/numeric literals now apply to these opaque (nonliteral) types
- e.g.
let a = E.A;
,a = E.B;
should be legal - Declaration file emit allows for initializers so that you can get both behaviors despite the fresh and nonfresh types having identical names
- 👉 5.0
- In 5.0 we unified
export
ordering (TC39 update)- Order 1:
@decorator export class X {
- Order 2:
export @decorator class X {
- Order 1 is the longstanding order in TS
- Order 2 came into existence due to a transcription error when writing the proposal
- Upon fixing the error, concerns were raised
- What if you want to "decorate an export" ?
- What does this mean?
- Sort of unclear, all possible things you could do here violate critical static invariants
- What does this mean?
- Various arguments ad linguistics of what's an adverb, adjective, conjunction junction what's your arrow function, etc.
- What if you want to have different behaviors between Order 1 and Order 2?
- But what?
- At best, you could have the inner and outer names of a class refer to the undecorated / decorated values, but this is a footgun
- If desired you can use proxies
- If this is legal, then
@deco1 export @deco2 class A {
becomes legal and sensical (!)
- What if you want to "decorate an export" ?
- TC39 Discussion continued for a long time without progress
- Decorators went to stage 3 without this being addressed
- Today
export @decorator class
is legal per TC39- In 5.0 today:
- In TS files, both orderings are supported with identical semantics
- In JS files, only
export @decorator class
is supported under non-experimental-decorators
- This has implications for
Function#toString
since decorators are supposed to be part oftoString
but notexport
- Arguments about
eval(someClass.toString())
but this is not an existing invariant anyway (?)
- Arguments about
- Do we need a transitional flag?
- Quickfix? Tool? Regular expression?
- These tools don't work on documentation on the internet
- This is an argument for making the proposal change, not making the behavior available in TS when it doesn't actually exist
- These tools don't work on documentation on the internet
- What are other transpilers doing?
- If we allow this (illegal!) syntax, then every TS-compatible transpiler has to as well, and it's a de facto JS feature
- But it's effectively moot since (all?) transpilers already presumably support
experimentalDecorators
- Babel issues a specific error
- Conclusions:
- Hope that both-orderings proposal goes through at TC39 and we don't have to make a tough decision
- Otherwise, circle back and argue about allowing flagged, unflagged, or not at all
- Update 2/2/23: Most of this turned out to be moot because both orderings were accepted at TC39 today 🎉
- Order 1: