Consider two TypeScript files:
_a.ts_
module M {
export var t = 5;
}
_b.ts_
var t = 'foo';
module M {
var s = t; // <-- what does this mean?
}
If we compile b.ts on its own, the t in var s = t refers to the outer var t, a string. The emit for this line is simply var s = t;.
If we compile b.ts along with a.ts, the t in var s = t refers to M.t, the exported variable of type number. The emit for this line is var s = M.t.
This behavior, and a few other language features (e.g. const enum), prevent TypeScript from being able to correctly operate on a single file without understanding the entire universe of files involved in the program. This has performance implications for features like compile-on-save, especially in larger projects, and blocks scenarios like on-the-fly compilation in module loaders.
We'd really prefer to be able to emit a file without first understanding the entire program it's a part of. The language as-is prevents this. However, by slightly subsetting the language to disallow things that require whole-program binding/typechecking, we can re-enable those scenarios. People can "opt in" their project to this language subset as a trade-off.
Tentatively, we're calling the prongs of this fork "whole program mode" and "single file mode". Naming TBD.
A key part of this is that you need to be able to compile e.g. a.ts and b.ts above in a mode that says "This code will not work in single-file-mode", e.g.:
> tsc --warnMeIfThisIsNotSafeInSingleFileMode a.ts b.ts
TS1234 (b.ts line 2): Modules may not be re-opened in single-file mode
We need some help naming these things, especially the commandline flag. The current list of ideas on the whiteboard, of which nobody likes anything, consists of the following 😦
separateCompile
singleFileEmit
disableGlobalOptimizations
safeForTranspile
safeForSyntacticTranspilation
separate
isolated
safeTransform
singleFileScope
crossFileSafe
crossFileRestrictions
Please help 🚲 🏠!
Ref #2499
Consider two TypeScript files:
_a.ts_
_b.ts_
If we compile b.ts on its own, the
tinvar s = trefers to the outer vart, astring. The emit for this line is simplyvar s = t;.If we compile b.ts along with a.ts, the
tinvar s = trefers toM.t, the exported variable of typenumber. The emit for this line isvar s = M.t.This behavior, and a few other language features (e.g.
const enum), prevent TypeScript from being able to correctly operate on a single file without understanding the entire universe of files involved in the program. This has performance implications for features like compile-on-save, especially in larger projects, and blocks scenarios like on-the-fly compilation in module loaders.We'd really prefer to be able to emit a file without first understanding the entire program it's a part of. The language as-is prevents this. However, by slightly subsetting the language to disallow things that require whole-program binding/typechecking, we can re-enable those scenarios. People can "opt in" their project to this language subset as a trade-off.
Tentatively, we're calling the prongs of this fork "whole program mode" and "single file mode". Naming TBD.
A key part of this is that you need to be able to compile e.g. a.ts and b.ts above in a mode that says "This code will not work in single-file-mode", e.g.:
We need some help naming these things, especially the commandline flag. The current list of ideas on the whiteboard, of which nobody likes anything, consists of the following 😦
separateCompilesingleFileEmitdisableGlobalOptimizationssafeForTranspilesafeForSyntacticTranspilationseparateisolatedsafeTransformsingleFileScopecrossFileSafecrossFileRestrictionsPlease help 🚲 🏠!
Ref #2499