Lazily Compute Module Shapes/APIs in --incremental
#42960
- When we are emitting all files under
--watch, we generate a .tsbuildinfo file. - Idea is, don't generate the
.d.ts emit for a file the first time. - Only when a single file changes, that's when we'll compute the change.
- But when we have
composite, we'll still have to do the .d.ts emit.
- So, unclear if this is what you want for
composite.
- The first change in any file will be unpredictable.
- Aside: do we need to hash
.d.ts emit?
- We could come up with an alternative - but
.d.ts is convenient.
- So you have to do more work on the subsequent change?
- Well, you're moving it to later.
- Kind of amortizing it.
- So with the
composite flag, ideally we'd want to reuse the .d.ts files since you're redoing all the same work.
- If you're using this for just type-checking with
--noEmit, the up-front benefit is great. - When do you lose?
tsc --watch, read the news, make a change, and a re-check is not that fast.- Is that compelling enough for a flag?
- Seems like no, nobody feels strongly enough.
- We want the change, need to review it.
assumeChangesAffectShape for --incremental and --watch scenarios
#41219
- If you don't have
.d.ts emit enabled, you have to still pay for the cost of .d.ts emit. - Idea: instead of consulting your
.d.ts files, every change impacts your dependencies. - Can we test with existing teams?
- They likely already have
.d.ts emit, not ideal
- Let's revisit.
Re-relax Index Signature Requirements
#43065
- Really, we're expanding the checks to cover 2 new cases.
- ✅
SomeObject -> { [x: string]: any } - ✅
SomeObject -> { [x: string]: any, [x: number]: any }
- Doesn't work for intersections of like
{ [x: string]: any } & { [x: number]: any } - kind of esoteric though. - No objections - looking for code review.
Experiments in Narrowing Generics
interfaceA{a: number|null;}functionget<T,KextendskeyofT>(obj: T,key: K){letp=obj[key];if(p!==null){letx: number=p;// doesn't narrow!}}- Want to be able to say when a type variable has a constraint, you want to lift that constraint up to an intersection of the type variable and its constraint.
T extends "a" | "b"- ->
T & ("a" | "b") - ->
T & "a" | T & "b".
- Once you do that, you can narrow those intersections with
x === "a" and x === "b" accordingly. - Reminds some of us of negated types.
- With negated types, we had perf problems of generating a ton of types.
- What about a constraint of
IntrinsicElements or something? - Is this something where we could have a size limit?
- Will this introduce a lot of subtype reduction?
- Think most code will have no effect at all?
- If we could make this efficient, could we do negated types?
- That's not why we didn't do negated types.
- "Yeah, but that's why I stopped bringing them up"
- 🤨
- Do we manufacture these unions of intersection lazily?
- Unclear - sounds like yes?
Lazily Compute Module Shapes/APIs in
--incremental#42960
--watch, we generate a.tsbuildinfofile..d.tsemit for a file the first time.composite, we'll still have to do the.d.tsemit.composite..d.tsemit?.d.tsis convenient.compositeflag, ideally we'd want to reuse the.d.tsfiles since you're redoing all the same work.--noEmit, the up-front benefit is great.tsc --watch, read the news, make a change, and a re-check is not that fast.assumeChangesAffectShapefor--incrementaland--watchscenarios#41219
.d.tsemit enabled, you have to still pay for the cost of.d.tsemit..d.tsfiles, every change impacts your dependencies..d.tsemit, not idealRe-relax Index Signature Requirements
#43065
SomeObject -> { [x: string]: any }SomeObject -> { [x: string]: any, [x: number]: any }{ [x: string]: any } & { [x: number]: any }- kind of esoteric though.Experiments in Narrowing Generics
T extends "a" | "b"T & ("a" | "b")T & "a" | T & "b".x === "a"andx === "b"accordingly.IntrinsicElementsor something?