Closed
Description
Project References
- Composite projects, cross-project references, "medium-sized" projects.
- We have interal teams that have upward of a million LOC in projects.
- Hitting memory limits, especially in editing scenarios where we have heavier ASTs.
- We don't have a well-prescribed way to break projects into smaller logical chunks.
- Idea: let's do something about it.
- What else have we tried?
- Everything else has implied strange rewrites, potentially dropping down to C.
- Pop quiz! Which is smaller?
4.8 MB of.ts
files, or 400KB of.d.ts
- Concept:
- Break projects into smaller projects that may depend each other.
- Reuse intermediate build results as often as possible.
- Type-check over the the
.d.ts
for a project reference instead of the.ts
files of the project.
- Type-check over the the
- What work do we have to do to figure out the outputs of a given set of input files & a
tsconfig.json
?- Well...
- Requires computing files output path relative to the outDir.
- Infer the
rootDir
. - Basically redo all of the module-heavy work.
- This leads to a new rule here:
rootDir
needs to be explicit, or is based on thetsconfig.json
location.
- Well...
- How do you determine whether input files are newer than output files?
- Have to do a bunch of work here!
- Have to have new inclusion rules.
include
rules have to be exhaustive.- Close to the same rules as
noResolve
.- "What does
noResolve
do again?"- Doesn't add files to the compilation context if included by a
/// <reference ... />
or animport
.
- Doesn't add files to the compilation context if included by a
- "What does
- Close to the same rules as
- "Reference targets"
- To reference a project, it must have
referenceTarget: true
(bikeshed on name later!) in thetsconfig.json
- Must have
--declaratin
- They get new
rootDir
and exhaustive resolution rules.
- To reference a project, it must have
tsbuild
- Performs graph ordering
- Potential for parallelization
- Demo: Dogfooding
- What's special about
tsc
?- Uses
--outFile
, not modules.
- Uses
- [[Look at this build dependency diagram!]]
- Wow, look at how many times we rebuild the TypeScript compiler sources today!
- No wonder it's slow!
- Wow, look at how many times we rebuild the TypeScript compiler sources today!
- [[Now look at how we organize this with reference targets.]]
- Let's try building this leaf with no dependents.
- [[Literal applause]]
- Let's try building
src/compiler/types.ts
- [[Sheer awe and excitement]]
- What sorts of improvements are we seeing on the compiler sources.
- Clean build: 110s -> 31s
- Modify a unit test: 26s -> 11s
- Clean build: 110s -> 13s
- Let's try building this leaf with no dependents.
- What's special about
- What about a project that uses modules?
- [[Imagine a project that has two front ends, some shared back-end dependencies, some respective utilities]]
- Remaining work
.d.ts
source-mapping so that language-service operations can work.- How does the language service work today?
- What about a cascading rename that affects siblings?
- What about circular project references?
- Source-maps currently turn to garbage
- There's apparently something called "source map indexes" but not everything supports it.
- This should be part of
tsc
itself.
Type Helpers in lib.d.ts
Diff
andOmit
- Potentially a breaking change for anyone using these as global.
- But not if they're using them for modules.
- Sounds like we want them
- Conclusion
- Run through DefinitelyTyped see what breaks.
ReturnType
- Does it also work on constructors?
- Ehh
- Yes
- Ehh
- Fine, we can have something separate.
- Problem: it always picks the last overload.
- Probably acceptable; can always custom-tailor your own conditional type.
- Does it also work on constructors?
DeepReadonly
- Conclusion: Nope, too special-cased.
- Doesn't handle readonly
Map
s andSet
s.
- Doesn't handle readonly
- Conclusion: Nope, too special-cased.
Spread
- Conclusion: you can define it yourself, but just make sure you define it in a module all you TypeScripters!
- Also different semantics for methods/function properties.
Array
/ReadonlyArray
mismatches
type Processor<T> = (subj: T) => void;
function doStuff<A, B extends A>(parentProcessors: Array<Processor<A>>, childProcessors: Array<Processor<B>>) {
childProcessors.concat(parentProcessors);
}
function foo<A, B extends A>() {
let aa
}
- Instantation with two "callback types" makes
ReadonlyArray
invariant and unrelated between the two. - Root of the problem is how we define
indexOf
.- Need a lower-bound constraint.
U super T
ofindexOf
.
- Need a lower-bound constraint.