We're planning the following set of deprecations for TypeScript 6.0. While TypeScript 6.0 will follow the same "soft deprecation" strategy as TypeScript 5.0, these options will be removed entirely in TypeScript 7 (the native TypeScript port).
Please let us know if these would be unreasonably disruptive for you by leaving a comment here.
In the two years since TypeScript 5.0, we've seen ongoing shifts in the JavaScript ecosystem:
- Virtually every runtime environment is now "evergreen". True legacy environments (ES5) are vanishingly rare
- Bundlers and ESM are the most common module environments, but CommonJS is still a major target. AMD and other in-browser userland module systems are much rarer than in 2012
- Almost all packages ship as some form of module. UMD packages still exist, but virtually no new code is only available as a global variable
tsconfig.json is nearly universal as a config mechanism
- Appetite for "stricter" typing continues to grow
- TypeScript build performance is top of mind. Despite the gains of TypeScript 7, we still must always have performance as a key goal, and options which can't be supported in a performant way need to be more strongly justified
Modernization
Newer Default Values
- The new default
target is es<current year> - done in #63067
- The new default
module is esnext
strict is now true by default
noUncheckedSideEffectImports is now true by default - done in #62443
libReplacement is now false by default done in #62391
--outFile removed
Removed for implementation simplicity's sake.
External bundlers or transpilers do this job faster, better, and more configurably.
Done in #62981
Removed Flag Values
module: amd, module: umd, and module: systemjs done in #62669
moduleResolution: classic done in #62669
esModuleInterop: false done in #62567
allowSyntheticDefaultImports: false done in #62567
target: es5 done in #63067
This also implies dropped support for the amd-module directive, which will no longer do anything.
--downlevelIteration removed
This flag only has effects on ES5 emit, which is deprecated; see #63071
Legacy module syntax
Early versions of TypeScript used this construct
which was later aliased to the modern preferred form
module blocks are a potential ECMAScript proposal which would conflict with this syntax, so we're fully deprecating using module where namespace is expected.
The ambient module declaration form
declare module "some-module" {
remains fully supported.
Done in #62876
See #61450 for RWC results
DOM tweaks
"lib": ["dom"] will now automatically include dom.iterable as well
Done in #62037
Performance
libReplacement defaults to false
This flag incurs a large number of failed module resolutions, which in turn increases the number of locations we need to watch under --watch and LSP scenarios. In a new project, libReplacement never does anything until other explicit configuration takes place, so it makes sense to turn this off by default.
Done in #62391
rootDir default
Currently rootDir, if not specified, is inferred based on the set of root files found (unless composite is set).
In 6.0, the default rootDir will always be the directory containing the tsconfig.json file.
If a non-config-based build occurs, rootDir will be inferred as before.
This lets us go faster because we don't need to compute the set of input files in order to determine the structure of the output directory.
Done in #62418
types default
Currently, the types value defaults to "enumerate everything in node_modules/@types". This is potentially very expensive as a normal repo setup these days might transitively pull in hundreds of @types packages. Modern projects almost always need only @types/node, @types/jest, or a handful of other common global-affecting packages.
In 6.0, the default types value will be [].
This will affect many projects; you will likely need to add "types": ["node"] or a few others.
This will prevent projects from unintentionally pulling in hundreds or even thousands of unneeded declaration files at build time. Many projects we've looked at have improved their build time anywhere from 20-50% just by setting types appropriately.
alwaysStrict
The alwaysStrict flag refers to inference of the "use strict"; directive. In TypeScript 6.0, all code will be assumed to be in "strict mode", which is a set of JS semantics that mostly affects syntactic corner cases around reserved words.
This lets us be faster because it's no longer necessary to look ahead or repase on constructs like
which is legal "sloppy mode" referring to a variable named await. This also reduces the number of flags which possibly prevent sharing of source files between projects with different compiler settings.
See #61888 for RWC run; we found one codebase that used static as a parameter name.
Behavorial Tweaks
no-default-lib directives
No one really understands what this does or uses it correctly. Done in #62435
Specifying commandline files when tsconfig.json exists is an error
Currently if you run tsc foo.ts in a folder where a tsconfig.json exists, the tsconfig file is completely ignored. This is very confusing. The intended meaning of this is also unclear; it could be that you want to use the compilerOptions of the config but not the files and/or include and/or exclude.
For clarity, in 6.0, if you run tsc in a directory with a tsconfig.json, an error will be issued instead.
tsconfig.json is present but will not be loaded if files are specified on the commandline. Use --ignore-config to skip this error
See also #27379. Done in #62477
JS Modernization
The asserts keyword was added to the JS language and then removed; in 6.0 this will be a parse error. See also #58453
Conditional imports/exports fallback lookups are deprecated; see #50762
If your name isn't Andrew Branch and you know what this even is about, please let us know.
See also #51000 / #51424 / #51909 / #54500
We're planning the following set of deprecations for TypeScript 6.0. While TypeScript 6.0 will follow the same "soft deprecation" strategy as TypeScript 5.0, these options will be removed entirely in TypeScript 7 (the native TypeScript port).
Please let us know if these would be unreasonably disruptive for you by leaving a comment here.
In the two years since TypeScript 5.0, we've seen ongoing shifts in the JavaScript ecosystem:
tsconfig.jsonis nearly universal as a config mechanismModernization
Newer Default Values
targetises<current year>- done in#63067moduleisesnextstrictis nowtrueby defaultnoUncheckedSideEffectImportsis nowtrueby default - done in#62443libReplacementis nowfalseby default done in#62391--outFileremovedRemoved for implementation simplicity's sake.
External bundlers or transpilers do this job faster, better, and more configurably.
Done in
#62981Removed Flag Values
module: amd,module: umd, andmodule: systemjsdone in#62669moduleResolution: classicdone in#62669esModuleInterop: falsedone in#62567allowSyntheticDefaultImports: falsedone in#62567target: es5done in#63067This also implies dropped support for the
amd-moduledirective, which will no longer do anything.--downlevelIterationremovedThis flag only has effects on ES5 emit, which is deprecated; see
#63071Legacy
modulesyntaxEarly versions of TypeScript used this construct
which was later aliased to the modern preferred form
moduleblocks are a potential ECMAScript proposal which would conflict with this syntax, so we're fully deprecating usingmodulewherenamespaceis expected.The ambient module declaration form
remains fully supported.
Done in
#62876See #61450 for RWC results
DOM tweaks
"lib": ["dom"]will now automatically includedom.iterableas wellDone in
#62037Performance
libReplacementdefaults to falseThis flag incurs a large number of failed module resolutions, which in turn increases the number of locations we need to watch under
--watchand LSP scenarios. In a new project,libReplacementnever does anything until other explicit configuration takes place, so it makes sense to turn this off by default.Done in
#62391rootDirdefaultCurrently
rootDir, if not specified, is inferred based on the set of root files found (unlesscompositeis set).In 6.0, the default
rootDirwill always be the directory containing thetsconfig.jsonfile.If a non-config-based build occurs,
rootDirwill be inferred as before.This lets us go faster because we don't need to compute the set of input files in order to determine the structure of the output directory.
Done in
#62418typesdefaultCurrently, the
typesvalue defaults to "enumerate everything innode_modules/@types". This is potentially very expensive as a normal repo setup these days might transitively pull in hundreds of@typespackages. Modern projects almost always need only@types/node,@types/jest, or a handful of other common global-affecting packages.In 6.0, the default
typesvalue will be[].This will affect many projects; you will likely need to add
"types": ["node"]or a few others.This will prevent projects from unintentionally pulling in hundreds or even thousands of unneeded declaration files at build time. Many projects we've looked at have improved their build time anywhere from 20-50% just by setting
typesappropriately.alwaysStrictThe
alwaysStrictflag refers to inference of the"use strict";directive. In TypeScript 6.0, all code will be assumed to be in "strict mode", which is a set of JS semantics that mostly affects syntactic corner cases around reserved words.This lets us be faster because it's no longer necessary to look ahead or repase on constructs like
which is legal "sloppy mode" referring to a variable named
await. This also reduces the number of flags which possibly prevent sharing of source files between projects with different compiler settings.See
#61888for RWC run; we found one codebase that usedstaticas a parameter name.Behavorial Tweaks
no-default-libdirectivesNo one really understands what this does or uses it correctly. Done in
#62435Specifying commandline files when
tsconfig.jsonexists is an errorCurrently if you run
tsc foo.tsin a folder where atsconfig.jsonexists, thetsconfigfile is completely ignored. This is very confusing. The intended meaning of this is also unclear; it could be that you want to use thecompilerOptionsof the config but not thefilesand/orincludeand/orexclude.For clarity, in 6.0, if you run
tscin a directory with atsconfig.json, an error will be issued instead.See also #27379. Done in
#62477JS Modernization
The
assertskeyword was added to the JS language and then removed; in 6.0 this will be a parse error. See also #58453Conditional imports/exports fallback lookups are deprecated; see #50762
If your name isn't Andrew Branch and you know what this even is about, please let us know.
See also #51000 / #51424 / #51909 / #54500