TSConfig Reference
# File Inclusion
These settings help you ensure that TypeScript picks up the right files.
# Files - files
Specifies an allowlist of files to include in the program. An error occurs if any of the files can’t be found.
{
"compilerOptions": {},
"files": [
"core.ts",
"sys.ts",
"types.ts",
"scanner.ts",
"parser.ts",
"utilities.ts",
"binder.ts",
"checker.ts",
"emitter.ts",
"program.ts",
"commandLineParser.ts",
"tsc.ts",
"diagnosticInformationMap.generated.ts"
]
}
This is useful when you only have a small number of files and don’t need to use a glob to reference many files.
If you need that then use include
.
Flag | files | |
Default | `false` |
# Include - include
Specifies an array of filenames or patterns to include in the program.
These filenames are resolved relative to the directory containing the tsconfig.json
file.
{
"include": ["src/**", "tests/**"]
}
Which would include:
.
├── scripts ⨯
│ ├── lint.ts ⨯
│ ├── update_deps.ts ⨯
│ └── utils.ts ⨯
├── src ✓
│ ├── client ✓
│ │ ├── index.ts ✓
│ │ └── utils.ts ✓
│ ├── server ✓
│ │ └── index.ts ✓
├── tests ✓
│ ├── app.test.ts ✓
│ ├── utils.ts ✓
│ └── tests.d.ts ✓
├── package.json
├── tsconfig.json
└── yarn.lock
include
and exclude
support wildcard characters to make glob patterns:
*
matches zero or more characters (excluding directory separators)?
matches any one character (excluding directory separators)**/
matches any directory nested to any level
If a glob pattern doesn’t include a file extension, then only files with supported extensions are included (e.g. .ts
, .tsx
, and .d.ts
by default, with .js
and .jsx
if allowJs
is set to true).
Flag | include | |
Default | `false` |
# Exclude - exclude
Specifies an array of filenames or patterns that should be skipped when resolving include
.
Important: exclude
only changes which files are included as a result of the include
setting.
A file specified by exclude
can still become part of your codebase due to an import
statement in your code, a types
inclusion, a /// <reference
directive, or being specified in the files
list.
It is not a mechanism that prevents a file from being included in the codebase - it simply changes what the include
setting finds.
Flag | exclude | |
Default | `false` |
# Extends - extends
The value of extends
is a string which contains a path to another configuration file to inherit from.
The path may use Node.js style resolution.
The configuration from the base file are loaded first, then overridden by those in the inheriting config file. All relative paths found in the configuration file will be resolved relative to the configuration file they originated in.
It’s worth noting that files
, include
and exclude
from the inheriting config file overwrite those from the
base config file, and that circularity between configuration files is not allowed.
Example
configs/base.json
:
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true
}
}
tsconfig.json
:
{
"extends": "./configs/base",
"files": ["main.ts", "supplemental.ts"]
}
tsconfig.nostrictnull.json
:
{
"extends": "./tsconfig",
"compilerOptions": {
"strictNullChecks": false
}
}
Flag | extends | |
Default | `false` |
# Type Acquisition - typeAcquisition
When you have a JavaScript project in your editor, TypeScript will provide types for your node_modules
automatically using the DefinitelyTyped set of @types
definitions.
This is called automatic type acquisition, and you can customize it using the typeAcquisition
object in your configuration.
If you would like to disable or customize this feature, create a jsconfig.json
in the root of your project:
{
"typeAcquisition": {
"enable": false
}
}
If you have a specific module which should be included (but isn’t in node_modules
):
{
"typeAcquisition": {
"include": ["jest"]
}
}
If a module should not be automatically acquired, for example if the library is available in your node_modules
but your team has agreed to not use it:
{
"typeAcquisition": {
"exclude": ["jquery"]
}
}
Flag | typeAcquisition | |
Default | `false` |
# References - references
Project references are a way to structure your TypeScript programs into smaller pieces. Using Project References can greatly improve build and editor interaction times, enforce logical separation between components, and organize your code in new and improved ways.
You can read more about how references works in the Project References section of the handbook
Flag | references | |
Default | `false` |
# Project Options
These settings are used to define the runtime expectations of your project, how and where you want the JavaScript to be emitted and the level of integration you want with existing JavaScript code.
# Incremental - incremental
Tells TypeScript to save information about the project graph from the last compilation to files stored on disk. This
creates a series of .tsbuildinfo
files in the same folder as your compilation output. They are not used by your
JavaScript at runtime and can be safely deleted. You can read more about the flag in the 3.4 release notes.
To control which folders you want to the files to be built to, use the config option tsBuildInfoFile
.
Flag | incremental | |
Default | `true` | |
Related | [`composite`](#composite), [`tsBuildInfoFile`](#tsBuildInfoFile) | |
Released | 3.4 |
# Target - target
Modern browsers support all ES6 features, so ES6
is a good choice.
You might choose to set a lower target if your code is deployed to older environments, or a higher target if your code is guaranteed to run in newer environments.
The target
setting changes which JS features are downleveled and which are left intact.
For example, an arrow function () => this
will be turned into an equivalent function
expression if target
is ES5 or lower.
Changing target
also changes the default value of lib
.
You may “mix and match” target
and lib
settings as desired, but you could just set target
for convenience.
If your are only working with Node.js, here are recommended target
based off of the Node version:
Name | Supported Target |
---|---|
Node 8 | ES2017 |
Node 10 | ES2018 |
Node 12 | ES2019 |
These are based on node.green’s database of support.
The special ESNext
value refers to the highest version your TypeScript supports.
This setting should be used with caution, since it doesn’t mean the same thing between different TypeScript versions and can make upgrades less predictable.
Flag | target | |
Default | `false` | |
Allowed | `ES3` (default), `ES5`, `ES6`/`ES2015` (synonomous), `ES7`/`ES2016`, `ES2017`, `ES2018`, `ES2019`, `ESNext` | |
Released | 1.0 |
# Module - module
Sets the module system for the program. See the [[Modules]] chapter for more information.
Flag | module | |
Allowed | `CommonJS` (default if `target` is `ES3` or `ES5`), `ES6`/`ES2015` (synonymous, default for `target` `ES6` and higher), `None`, `UMD`, `AMD`, `System`, `ESNext` | |
Released | 1.0 |
# Lib - lib
TypeScript includes a default set of type definitions for built-in JS APIs (like Math
), as well as type definitions for things found in browser environments (like document
).
TypeScript also includes APIs for newer JS features matching the target
you specify; for example the definition for Map
is available if target
is ES6
or newer.
You may want to change these for a few reasons:
- Your program doesn’t run in a browser, so you don’t want the
"dom"
type definitions - Your runtime platform provides certain JavaScript API objects (maybe through polyfills), but doesn’t yet support the full syntax of a given ECMAScript version
- You have polyfills or native implementations for some, but not all, of a higher level ECMAScript version
High Level libraries
Name | Contents |
---|---|
ES5 |
Core definitions for all ES3 and ES5 functionality |
ES2015 |
Additional APIs available in ES2015 (also known as ES6) - array.find , Promise , Proxy , Symbol , Map , Set , Reflect , etc. |
ES6 |
Alias for “ES2015” |
ES2016 |
Additional APIs available in ES2016 - array.include , etc. |
ES7 |
Alias for “ES2016” |
ES2017 |
Additional APIs available in ES2017 - Object.entries , Object.values , Atomics , SharedArrayBuffer , date.formatToParts , typed arrays, etc. |
ES2018 |
Additional APIs available in ES2018 - async iterables, promise.finally , Intl.PluralRules , rexexp.groups , etc. |
ES2019 |
Additional APIs available in ES2019 - array.flat , array.flatMap , Object.fromEntries , string.trimStart , string.trimEnd , etc. |
ES2020 |
Additional APIs available in ES2020 - string.matchAll , etc. |
ESNext |
Additional APIs available in ESNext - This changes as the JavaScript specification evolves |
DOM |
DOM definitions - window , document , etc. |
WebWorker |
APIs available in WebWorker contexts |
ScriptHost |
APIs for the Windows Script Hosting System |
Individual library components
Name |
---|
DOM.Iterable |
ES2015.Core |
ES2015.Collection |
ES2015.Generator |
ES2015.Iterable |
ES2015.Promise |
ES2015.Proxy |
ES2015.Reflect |
ES2015.Symbol |
ES2015.Symbol.WellKnown |
ES2016.Array.Include |
ES2017.object |
ES2017.Intl |
ES2017.SharedMemory |
ES2017.String |
ES2017.TypedArrays |
ES2018.Intl |
ES2018.Promise |
ES2018.RegExp |
ES2019.Array |
ES2019.Full |
ES2019.Object |
ES2019.String |
ES2019.Symbol |
ES2020.Full |
ES2020.String |
ES2020.Symbol.wellknown |
ESNext.AsyncIterable |
ESNext.Array |
ESNext.Intl |
ESNext.Symbol |
This list may be out of date, you can see the full list in the TypeScript source code.
Flag | lib | |
Released | 2.0 |
# Allow JS - allowJs
Allow JavaScript files to be imported inside your project, instead of just .ts
and .tsx
files. For example, this JS file:
js// @filename: card.js export const defaultCardDeck = "Heart";
When imported into a TypeScript file will raise an error:
ts// @filename: index.ts import { (alias) (property) defaultCardDeck: string import defaultCardDeckk(alias) (property) defaultCardDeck: string import defaultCardDeck } f(alias) (property) defaultCardDeck: string import defaultCardDeckrom "./card"; console.log(defaultCardDeck);
Imports fine with allowJs
enabled:
ts// @filename: index.ts import { (alias) (property) defaultCardDeck: string import defaultCardDeckk(alias) (property) defaultCardDeck: string import defaultCardDeck } f(alias) (property) defaultCardDeck: string import defaultCardDeckrom "./card"; console.log(defaultCardDeck);
This flag can be used as a way to incrementally add TypeScript files into JS projects by allowing the .ts
and .tsx
files to live along-side existing JavaScript files.
Flag | allowJs | |
Default | `false` | |
Released | 1.8 |
# Check JS - checkJs
Works in tandem with allowJs
. When checkJs
is enabled then errors are reported in JavaScript files. This is
the equivalent of including // @ts-check
at the top of all JavaScript files which are included in your project.
For example, this is incorrect JavaScript according to the parseFloat
type definition which comes with TypeScript:
// parseFloat only takes a string
module.exports.pi = parseFloat(3.124);
When imported into a TypeScript module:
ts// @filename: constants.js /// <reference types="node" /> module.exports.pi = parseFloat(3.124); // @filename: index.ts import { pi } from "./constants"; console.log(pi);
You will not get any errors. However, if you turn on checkJs
then you will get error messages from the JavaScript file.
ts// @filename: constants.js /// <reference types="node" /> Argument of type '3.124' is not assignable to parameter of type 'string'.2345Argument of type '3.124' is not assignable to parameter of type 'string'.module.exports.pi = parseFloat(3.124); // @filename: index.ts import { pi } from "./constants"; console.log(pi);
Flag | checkJs | |
Default | `false` |
# JSX - jsx
Controls how JSX constructs are emitted in JavaScript files.
This only affects output of JS files that started in .tsx
files.
preserve
: Emit.jsx
files with the JSX unchangedreact
: Emit.js
files with JSX changed to the equivalentReact.createElement
callsreact-native
: Emit.js
files with the JSX unchanged
Flag | jsx | |
Default | `"preserve"` | |
Allowed | `react` (default), `react-native`, `preserve` | |
Released | 2.2 |
# Declaration - declaration
Generate d.ts
files for every TypeScript or JavaScript file inside your project.
These d.ts
files are type definition files which describe the external API of your module.
With d.ts
files, tools like TypeScript can provide intellisense and accurate types for un-typed code.
When declaration
is set to true
, running the compiler with this TypeScript code:
tsexport const helloWorldconst helloWorld: "hi" = "hi";
Will generate an index.js
file like this:
jsexport const helloWorld = "hi";
With a corresponding helloWorld.d.ts
:
// @showEmittedFile: index.d.ts
// @showEmit
// @declaration
export declare const helloWorld = "hi";
Flag | declaration | |
Default | True when TS | |
Released | 1.0 |
# Declaration Map - declarationMap
Generates a source map for .d.ts
files which map back to the original .ts
source file.
This will allow editors such as VS Code to go to the original .ts
file when using features like Go to Definition.
You should strongly consider turning this on if you’re using project references.
Flag | declarationMap | |
Default | `false` | |
Released | 2.9 |
# Source Map - sourceMap
Enables the generation of sourcemap files.
These files allow debuggers and other tools to display the original TypeScript source code when actually working with the emitted JavaScript files.
Source map files are emitted as .js.map
(or .jsx.map
) files next to the corresponding .js
output file.
The .js
files will in turn contain a sourcemap comment to indicate to tools where the files are to external tools, for example:
// helloWorld.ts
export declare const helloWorld = "hi";
Compiling with sourceMap
set to true
creates the following JavaScript file:
// helloWorld.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.helloWorld = "hi";
//# sourceMappingURL=// helloWorld.js.map
And this also generates this json map:
// helloWorld.js.map
{
"version": 3,
"file": "ex.js",
"sourceRoot": "",
"sources": ["../ex.ts"],
"names": [],
"mappings": ";;AAAa,QAAA,UAAU,GAAG,IAAI,CAAA"
}
Flag | sourceMap | |
Default | `false` |
# Out File - outFile
If specified, all global (non-module) files will be concatenated into the single output file specified.
If module
is system
or amd
, all module files will also be concatenated into this file after all global content.
Note: outFile
cannot be used unless module
is None
, System
, or AMD
.
This option cannot be used to bundle CommonJS or ES6 modules.
Flag | outFile | |
Default | `n/a` | |
Related | [`out`](#out), [`outDir`](#outDir) | |
Released | 1.0 |
# Out Dir - outDir
If specified, .js
(as well as .d.ts
, .js.map
, etc.) files will be emitted in the specified directory.
The directory structure of the original source files is preserved; see rootDir if the computed root is not what you intended.
If not specified, .js
files will be emitted in the same directory as the .ts
files they were generated from.
Flag | outDir | |
Default | `n/a` | |
Related | [`out`](#out), [`outFile`](#outFile) |
# Root Dir - rootDir
Default: The longest common path of all non-declaration input files. If composite
is set, the default is instead the directory containing the tsconfig.json
file.
When TypeScript compiles files, it keeps the same directory structure in the output directory as exists in the input directory.
For example, let’s say you have some input files:
MyProj
├── tsconfig.json
├── core
│ ├── a.ts
│ ├── b.ts
│ ├── sub
│ │ ├── c.ts
├── types.d.ts
The inferred value for rootDir
is the longest common path of all non-declaration input files, which in this case is core/
.
If your outDir
was dist
, TypeScript would write this tree:
MyProj
├── dist
│ ├── a.ts
│ ├── b.ts
│ ├── sub
│ │ ├── c.ts
However, you may have intended for core
to be part of the output directory structure.
By setting rootDir: "."
in tsconfig.json
, TypeScript would write this tree:
MyProj
├── dist
| ├── core
│ │ ├── a.ts
│ │ ├── b.ts
│ │ ├── sub
│ │ │ ├── c.ts
Importantly, rootDir
does not affect which files become part of the compilation.
It has no interaction with the include
, exclude
, or files
tsconfig.json
settings.
Note that TypeScript will never write an output file to a directory outside of outDir
, and will never skip emitting a file.
For this reason, rootDir
also enforces that all files which need to be emitted are underneath the rootDir
path.
For example, let’s say you had this tree:
MyProj
├── tsconfig.json
├── core
│ ├── a.ts
│ ├── b.ts
├── helpers.ts
It would be an error to specify rootDir
as core
and include
as *
because it creates a file (helpers.ts
) that would need to be emitted outside the outDir
(i.e. ../helpers.js
).
Flag | rootDir | |
Default | Computed from the list of input files | |
Released | 1.5 |
# Composite - composite
The composite
option enforces certain constraints which make it possible for build tools (including TypeScript
itself, under --build
mode) to quickly determine if a project has been built yet.
When this setting is on:
- The
rootDir
setting, if not explicitly set, defaults to the directory containing thetsconfig.json
file. - All implementation files must be matched by an
include
pattern or listed in thefiles
array. If this constraint is violated,tsc
will inform you which files weren’t specified. declaration
defaults totrue
You can find documentation on TypeScript projects in the handbook.
Flag | composite | |
Default | `true` | |
Related | [`incremental`](#incremental), [`tsBuildInfoFile`](#tsBuildInfoFile) | |
Released | 3.0 |
# TS Build Info File - tsBuildInfoFile
This setting lets you specify a file for storing incremental compilation information as a part of composite projects which enables faster building of larger TypeScript codebases. You can read more about composite projects in the handbook.
This option offers a way to configure the place where TypeScript keeps track of the files it stores on the disk to indicate a project’s build state — by default, they are in the same folder as your emitted JavaScript.
Flag | tsBuildInfoFile | |
Default | .tsbuildinfo | |
Released | 3.4 |
# Remove Comments - removeComments
Strips all comments from TypeScript files when converting into JavaScript. Defaults to true
.
For example, this is a TypeScript file which has a JSDoc comment:
/** The translation of 'Hello world' into Portuguese */
export const helloWorldPTBR = "Olá Mundo";
Without setting removeComments
or having it as true
:
js/** The translation of 'Hello world' into Portuguese */ export const helloWorldPTBR = "Olá Mundo";
When removeComments
is set to false
:
js/** The translation of 'Hello world' into Portuguese */ export const helloWorldPTBR = "Olá Mundo";
This means that your comments will show up in the JavaScript code.
Flag | removeComments | |
Default | `false` |
# No Emit - noEmit
Do not emit compiler output files like JavaScript source code, source-maps or declarations.
This makes room for another tool like Babel, or swc to handle converting the TypeScript file to a file which can run inside a JavaScript environment.
You can then use TypeScript as a tool for providing editor integration, and as a source code type-checker.
Flag | noEmit | |
Default | `false` |
# Import Helpers - importHelpers
For certain downleveling operations, TypeScript uses some helper code for operations like extending class, spreading arrays or objects, and async operations. By default, these helpers are inserted into files which use them. This can result in code duplication if the same helper is used in many different modules.
If the importHelpers
flag is on, these helper functions are instead imported from the tslib module.
You will need to ensure that the tslib
module is able to be imported at runtime.
This only affects modules; global script files will not attempt to import modules.
For example, with this TypeScript:
export function fn(arr: number[]) {
const arr2 = [1, ...arr];
}
Turning on downlevelIteration
and importHelpers
is still false:
js"use strict"; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spread = (this && this.__spread) || function () { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; }; Object.defineProperty(exports, "__esModule", { value: true }); function fn(arr) { var arr2 = __spread([1], arr); } exports.fn = fn;
Then turning on both downlevelIteration
and importHelpers
:
js"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); function fn(arr) { var arr2 = tslib_1.__spread([1], arr); } exports.fn = fn;
You can use noEmitHelpers
when you provide your own implementations of these functions.
Flag | importHelpers | |
Default | `false` | |
Related | [`noEmitHelpers`](#noEmitHelpers), [`downlevelIteration`](#downlevelIteration), [`importHelpers`](#importHelpers) |
# Downlevel Iteration - downlevelIteration
Downleveling is TypeScript’s term for transpiling to an older version of JavaScript. This flag is to enable support for a more accurate implementation of how modern JavaScript iterates through new concepts in older JavaScript runtimes.
ECMAScript 6 added several new iteration primitives: the for / of
loop (for (el of arr)
), Array spread ([a, ...b]
), argument spread (fn(...args)
), and Symbol.iterator
.
--downlevelIteration
allows for these iteration primitives to be used more accurately in ES5 environments if a Symbol.iterator
implementation is present.
Example: Effects on for / of
Without downlevelIteration
on, a for / of
loop on any object is downleveled to a traditional for
loop:
js"use strict"; var str = "Hello!"; for (var _i = 0, str_1 = str; _i < str_1.length; _i++) { var s = str_1[_i]; console.log(s); }
This is often what people expect, but it’s not 100% compliant with ECMAScript 6 behavior.
Certain strings, such as emoji (😜), have a .length
of 2 (or even more!), but should iterate as 1 unit in a for-of
loop.
See this blog post by Jonathan New for a longer explanation.
When downlevelIteration
is enabled, TypeScript will use a helper function that checks for a Symbol.iterator
implementation (either native or polyfill).
If this implementation is missing, you’ll fall back to index-based iteration.
js"use strict"; var __values = (this && this.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; var e_1, _a; var str = "Hello!"; try { for (var str_1 = __values(str), str_1_1 = str_1.next(); !str_1_1.done; str_1_1 = str_1.next()) { var s = str_1_1.value; console.log(s); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (str_1_1 && !str_1_1.done && (_a = str_1.return)) _a.call(str_1); } finally { if (e_1) throw e_1.error; } }
Note: enabling
downlevelIteration
does not improve compliance ifSymbol.iterator
is not present in the runtime.
Example: Effects on Array Spreads
This is an array spread:
// Make a new array who elements are 1 followed by the elements of arr2
const arr = [1, ...arr2];
Based on the description, it sounds easy to downlevel to ES5:
// The same, right?
const arr = [1].concat(arr2);
However, this is observably different in certain rare cases.
For example, if an array has a “hole” in it, the missing index will create an own property if spreaded, but will not if built using concat
:
// Make an array where the '1' element is missing
let missing = [0, , 1];
let spreaded = [...missing];
let concated = [].concat(missing);
// true
"1" in spreaded;
// false
"1" in concated;
Just as with for / of
, downlevelIteration
will use Symbol.iterator
(if present) to more accurately emulate ES 6 behavior.
Flag | downlevelIteration | |
Default | `false` | |
Released | 2.3 |
# Isolated Modules - isolatedModules
While you can use TypeScript to produce JavaScript code from TypeScript code, it’s also common to use other transpilers such as Babel to do this.
However, most other transpilers only operate on a single file at a time, so can’t apply code transforms that depend on whole-program analysis.
This restriction also applies to TypeScript’s ts.transpileModule
API which is used by some build tools.
These limitations can cause runtime problems for some TypeScript constructs.
Setting the isolatedModules
flag tells TypeScript to warn you if you write certain code that can’t be correctly interpreted by a single-file transpilation process.
It does not change the behavior of your code, or otherwise change the behavior of TypeScript’s checking and emitting process.
Exports of Non-Value Identifiers
In TypeScript, you can import a type and then subsequently export it:
tsimport { someTypeimport someType, someFunctionimport someFunction } from "someModule"; someFunctionimport someFunction(); export { someTypeexport someType, someFunctionexport someFunction };
Because there’s no value for someType
, the emitted export
will not try to export it (this would be a runtime error):
export { someFunction };
Single-file transpilers don’t know whether someType
produces a value or not, so it’s an error to export a name that only refers to a type if isolatedModules
is set.
Non-Module Files
If isolatedModules
is set, all implementation files must be modules.
An error occurs if any file isn’t a module:
tsfunction fnfunction fn(): void() {} All files must be modules when the '--isolatedModules' flag is provided.1208All files must be modules when the '--isolatedModules' flag is provided.
This restriction doesn’t apply to .d.ts
files
References to const enum
members
In TypeScript, when you reference a const enum
member, the reference is replaced by its actual value in the emitted JavaScript:
declare const enum Numbers {
Zero = 0,
One = 1
}
console.log(Numbers.Zero + Numbers.One);
To:
js"use strict"; console.log(0 + 1);
Without knowledge of the values of these members, other transpilers can’t replace the references to Number
, which would be a runtime error if left alone (since there is no Numbers
object at runtime).
Because of this, when isolatedModules
is set, it is an error to reference an ambient const enum
member.
Flag | isolatedModules | |
Default | `false` |
# Strict Checks
TypeScript supports a spectrum of JavaScript patterns, TypeScript patterns and strives for backwards compatibility with them all.
Upgrading to a new version of TypeScript can uncover two types of errors:
- Errors which already exist in your codebase, TypeScript has uncovered because the language has become refined it’s understanding of JavaScript.
- A new suite of errors which tackle a whole new problem domain.
TypeScript will usually add a compiler flag for the latter set of errors, and by default these are not enabled.
If you want to ensure that your codebase is as correct as possible, then use the option strict
to opt-in to every possible improvement as they are built.
# Strict - strict
The strict
flag enables a wide range of type checking behavior that results in stronger guarantees of program correctness.
Turning this on is equivalent to enabling all of the strict mode family options, which are outlined below.
You can then turn off individual strict mode family checks as needed.
Future versions of TypeScript may introduce additional stricter checking under this flag, so upgrades of TypeScript might result in new type errors in your program. When appropriate and possible, a corresponding flag will be added to disable that behavior.
Flag | strict | |
Recommended | True | |
Default | `false` | |
Related | [`strictBindCallApply`](#strictBindCallApply), [`strictFunctionTypes`](#strictFunctionTypes), [`strictPropertyInitialization`](#strictPropertyInitialization) | |
Released | 2.3 |
# No Implicit Any - noImplicitAny
In some cases where no type annotations are present, TypeScript will fall back to a type of any
for a variable when it cannot infer the type.
This can cause some errors to be missed, for example:
tsfunction fnfunction fn(s: any): void(s(parameter) s: any) { // No error? consolevar console: Console.log(method) Console.log(message?: any, ...optionalParams: any[]): void(s(parameter) s: any.subtrany(3)); } fnfunction fn(s: any): void(42);
Turning on noImplicitAny
however TypeScript will issue an error whenever it would have inferred any
:
tsfunction fnfunction fn(s: any): void(s(parameter) s: any) { Parameter 's' implicitly has an 'any' type.7006Parameter 's' implicitly has an 'any' type. consolevar console: Console.log(method) Console.log(message?: any, ...optionalParams: any[]): void(s(parameter) s: any.subtrany(3)); }
Flag | noImplicitAny | |
Recommended | True | |
Default | `false`, unless `strict` is set |
# Strict Null Checks - strictNullChecks
When strictNullChecks
is false
, null
and undefined
are effectively ignored by the language.
This can lead to unexpected errors at runtime.
When strictNullChecks
is true
, null
and undefined
have their own distinct types and you’ll get a type error if you try to use them where a concrete value is expected.
For example with this TypeScript code, users.find
has no guarantee that it will actually find a user, but you can
write code as though it will:
tsdeclare const loggedInUsernameconst loggedInUsername: string: string; const usersconst users: { name: string; age: number; }[] = [ { name(property) name: string: "Oby", age(property) age: number: 12 }, { name(property) name: string: "Heera", age(property) age: number: 32 } ]; const loggedInUserconst loggedInUser: { name: string; age: number; } = usersconst users: { name: string; age: number; }[].find(method) Array<{ name: string; age: number; }>.find(predicate: (value: { name: string; age: number; }, index: number, obj: { name: string; age: number; }[]) => unknown, thisArg?: any): { name: string; age: number; } (+1 overload)(u(parameter) u: { name: string; age: number; } => u(parameter) u: { name: string; age: number; }.name(property) name: string === loggedInUsernameconst loggedInUsername: string); consolevar console: Console.log(method) Console.log(message?: any, ...optionalParams: any[]): void(loggedInUserconst loggedInUser: { name: string; age: number; }.age(property) age: number);
Setting strictNullChecks
to true
will raise an error that you have not made a guarantee that the loggedInUser
exists before trying to use it.
tsdeclare const loggedInUsernameconst loggedInUsername: string: string; const usersconst users: { name: string; age: number; }[] = [ { name(property) name: string: "Oby", age(property) age: number: 12 }, { name(property) name: string: "Heera", age(property) age: number: 32 } ]; const loggedInUserconst loggedInUser: { name: string; age: number; } | undefined = usersconst users: { name: string; age: number; }[].find(method) Array<{ name: string; age: number; }>.find(predicate: (value: { name: string; age: number; }, index: number, obj: { name: string; age: number; }[]) => unknown, thisArg?: any): { name: string; age: number; } | undefined (+1 overload)(u(parameter) u: { name: string; age: number; } => u(parameter) u: { name: string; age: number; }.name(property) name: string === loggedInUsernameconst loggedInUsername: string); consolevar console: Console.log(method) Console.log(message?: any, ...optionalParams: any[]): void(loggedInUserconst loggedInUser: { name: string; age: number; } | undefined.age(property) age: number); Object is possibly 'undefined'.2532Object is possibly 'undefined'.
The second example failed because the array’s find
function looks a bit like this simplification:
// When strictNullChecks: true
type Array = {
find(predicate: (value: any, index: number) => boolean): S | undefined;
};
// When strictNullChecks: false the undefined is removed from the type system,
// allowing you to write code which assumes it always found a result
type Array = {
find(predicate: (value: any, index: number) => boolean): S;
};
Flag | strictNullChecks | |
Recommended | True | |
Default | `false` | |
Released | 2.0 |
# Strict Function Types - strictFunctionTypes
When enabled, this flag causes functions parameters to be checked more correctly.
Here’s a basic example with strictFunctionTypes
off:
tsfunction fnfunction fn(x: string): void(x(parameter) x: string: string) { consolevar console: Console.log(method) Console.log(message?: any, ...optionalParams: any[]): void("Hello, " + x(parameter) x: string.toLowerCase(method) String.toLowerCase(): string()); } type StringOrNumberFunctype StringOrNumberFunc = (ns: string | number) => void = (ns(parameter) ns: string | number: string | number) => void; // Unsafe assignment let funclet func: StringOrNumberFunc: StringOrNumberFunctype StringOrNumberFunc = (ns: string | number) => void = fnfunction fn(x: string): void; // Unsafe call - will crash funclet func: (ns: string | number) => void(10);
With strictFunctionTypes
on, the error is correctly detected:
tsfunction fnfunction fn(x: string): void(x(parameter) x: string: string) { consolevar console: Console.log(method) Console.log(message?: any, ...optionalParams: any[]): void("Hello, " + x(parameter) x: string.toLowerCase(method) String.toLowerCase(): string()); } type StringOrNumberFunctype StringOrNumberFunc = (ns: string | number) => void = (ns(parameter) ns: string | number: string | number) => void; // Unsafe assignment is prevented let funclet func: StringOrNumberFunc: StringOrNumberFunctype StringOrNumberFunc = (ns: string | number) => void = fnfunction fn(x: string): void; Type '(x: string) => void' is not assignable to type 'StringOrNumberFunc'. Types of parameters 'x' and 'ns' are incompatible. Type 'string | number' is not assignable to type 'string'. Type 'number' is not assignable to type 'string'.2322Type '(x: string) => void' is not assignable to type 'StringOrNumberFunc'. Types of parameters 'x' and 'ns' are incompatible. Type 'string | number' is not assignable to type 'string'. Type 'number' is not assignable to type 'string'.
During development of this feature, we discovered a large number of inherently unsafe class hierarchies, including some in the DOM. Because of this, the setting only applies to functions written in function syntax, not to those in method syntax:
tstype Methodishtype Methodish = { func(x: string | number): void; } = { func(method) func(x: string | number): void(x(parameter) x: string | number: string | number): void; }; function fnfunction fn(x: string): void(x(parameter) x: string: string) { consolevar console: Console.log(method) Console.log(message?: any, ...optionalParams: any[]): void("Hello, " + x(parameter) x: string.toLowerCase(method) String.toLowerCase(): string()); } // Ultimately an unsafe assignment, but not detected const mconst m: Methodish: Methodishtype Methodish = { func(x: string | number): void; } = { func(method) func(x: string | number): void: fnfunction fn(x: string): void }; mconst m: Methodish.func(method) func(x: string | number): void(10);
Flag | strictFunctionTypes | |
Recommended | True | |
Default | `false` | |
Released | 2.6 |
# Strict Bind Call Apply - strictBindCallApply
Default: false
, unless strict
is set.
When set, TypeScript will check that the built-in methods of functions call
, bind
, and apply
are invoked with correct argument for the underlying function:
// With strictBindCallApply on
function fn(x: string) {
return parseInt(x);
}
const n1 = fn.call(undefined, "10");
^?
const n2 = fn.call(undefined, false);
Otherwise, these functions accept any arguments and will return any
:
// @strictBindCallApply: false
// With strictBindCallApply off
function fn(x: string) {
return parseInt(x);
}
// Note: No error; return type is 'any'
const n = fn.call(undefined, false);
^?
Flag | strictBindCallApply | |
Recommended | True | |
Default | `false` | |
Released | 3.2 |
# Strict Property Initialization - strictPropertyInitialization
When set to true, TypeScript will raise an error when a class property was declared but not set in the constructor.
tsclass UserAccountclass UserAccount { name(property) UserAccount.name: string: string; accountType = "user"; email(property) UserAccount.email: string: string; Property 'email' has no initializer and is not definitely assigned in the constructor.2564Property 'email' has no initializer and is not definitely assigned in the constructor. address(property) UserAccount.address: string | undefined: string | undefined; constructor(name(parameter) name: string: string) { this.name(property) UserAccount.name: string = name(parameter) name: string; // Note that this.email is not set } }
In the above case:
this.name
is set specifically.this.accountType
is set by default.this.email
is not set and raises an error.this.address
is declared as potentiallyundefined
which means it does not have to be set.
Flag | strictPropertyInitialization | |
Default | `false` | |
Released | 2.7 |
# No Implicit This - noImplicitThis
Raise error on ‘this’ expressions with an implied ‘any’ type.
For example, the class below returns a function which tries to access this.width
and this.height
– but the context
for this
inside the function inside getAreaFunction
is not the instance of the Rectangle.
tsclass Rectangleclass Rectangle { width(property) Rectangle.width: number: number; height(property) Rectangle.height: number: number; constructor(width(parameter) width: number: number, height(parameter) height: number: number) { this.width(property) Rectangle.width: number = width(parameter) width: number; this.height(property) Rectangle.height: number = height(parameter) height: number; } getAreaFunction(method) Rectangle.getAreaFunction(): () => number() { return function() { return this.widthany * this.heightany; 'this' implicitly has type 'any' because it does not have a type annotation.'this' implicitly has type 'any' because it does not have a type annotation.2683
2683'this' implicitly has type 'any' because it does not have a type annotation.'this' implicitly has type 'any' because it does not have a type annotation. }; } }
Flag | noImplicitThis | |
Recommended | True | |
Default | `false`, unless `strict` is set | |
Released | 2.0 |
# Always Strict - alwaysStrict
Ensures that your files are parsed in the ECMAScript strict mode, and emit “use strict” for each source file.
ECMAScript strict mode was introduced in ES5 and provides behavior tweaks to the runtime of the JavaScript engine to improve performance, and makes a set of errors throw instead of silently ignoring them.
Flag | alwaysStrict | |
Default | `false`, unless `strict` is set | |
Released | 2.1 |
# Module Resolution
Additional Checks Copy
# Module Resolution - moduleResolution
Specify module resolution strategy: ‘node’ (Node.js) or ‘classic’ (TypeScript pre-1.6). You probably won’t need to use this.
Flag | moduleResolution | |
Status | Deprecated | |
Status | Deprecated |
# Base Url - baseUrl
Lets you set a base directory to resolve non-absolute module names.
You can define a root folder where you can do absolute file resolution. E.g.
baseUrl
├── ex.ts
├── hello
│ └── world.ts
└── tsconfig.json
With "baseUrl": "./"
inside this project TypeScript will look for files starting at the same folder as the tsconfig.json
.
import { helloWorld } from "hello/world";
console.log(helloWorld);
If you get tired of imports always looking like "../"
or "./"
. Or needing
to change as you move files, this is a great way to fix that.
Flag | baseUrl |
# Paths - paths
A series of entries which re-map imports to lookup locations relative to the baseUrl
, there is a larger coverage of paths
in the handbook.
paths
lets you declare how TypeScript should resolve an import in your require
/import
s.
{
"compilerOptions": {
"baseUrl": ".", // this must be specified if "paths" is specified.
"paths": {
"jquery": ["node_modules/jquery/dist/jquery"] // this mapping is relative to "baseUrl"
}
}
}
This would allow you to be able to write import "jquery"
, and get all of the correct typing locally.
{
"compilerOptions": {
"baseUrl": "src",
"paths": {
"app/*": ["app/*"],
"config/*": ["app/_config/*"],
"environment/*": ["environments/*"],
"shared/*": ["app/_shared/*"],
"helpers/*": ["helpers/*"],
"tests/*": ["tests/*"]
},
}
In this case, you can tell the TypeScript file resolver to support a number of custom prefixes to find code. This pattern can be used to avoid long relative paths within your codebase.
Flag | paths |
# Root Dirs - rootDirs
Using rootDirs
, you can inform the compiler that there are many “virtual” directories acting as a single root.
This allows the compiler to resolve relative module imports within these “virtual” directories, as if they were merged in to one directory.
For example:
src
└── views
└── view1.ts (can import "./template1", "./view2`)
└── view2.ts (can import "./template1", "./view1`)
generated
└── templates
└── views
└── template1.ts (can import "./view1", "./view2")
{
"compilerOptions": {
"rootDirs": ["src/views", "generated/templates/views"]
}
}
This does not affect how TypeScript emits JavaScript, it only emulates the assumption that they will be able to work via those relative paths at runtime.
Flag | rootDirs | |
Released | 2.0 |
# Type Roots - typeRoots
By default all visible ”@types
” packages are included in your compilation.
Packages in node_modules/@types
of any enclosing folder are considered visible.
For example, that means packages within ./node_modules/@types/
, ../node_modules/@types/
, ../../node_modules/@types/
, and so on.
If typeRoots
is specified, only packages under typeRoots
will be included. For example:
{
"compilerOptions": {
"typeRoots": ["./typings", "./vendor/types"]
}
}
This config file will include all packages under ./typings
and ./vendor/types
, and no packages from ./node_modules/@types
.
All paths are relative to the tsconfig.json
.
Flag | typeRoots | |
Related | [`types`](#types) |
# Types - types
By default all visible ”@types
” packages are included in your compilation.
Packages in node_modules/@types
of any enclosing folder are considered visible.
For example, that means packages within ./node_modules/@types/
, ../node_modules/@types/
, ../../node_modules/@types/
, and so on.
If types
is specified, only packages listed will be included. For instance:
{
"compilerOptions": {
"types": ["node", "lodash", "express"]
}
}
This tsconfig.json
file will only include ./node_modules/@types/node
, ./node_modules/@types/lodash
and ./node_modules/@types/express
.
Other packages under node_modules/@types/*
will not be included.
This feature differs from typeRoots
in that it is about specifying only the exact types you want included, whereas typeRoots
supports saying you want particular folders.
Flag | types | |
Related | [`typeRoots`](#typeRoots) |
# Allow Synthetic Default Imports - allowSyntheticDefaultImports
When set to true, allowSyntheticDefaultImports
let’s you write an import like:
import React from "react";
instead of:
import * as React from "react";
When the module does not specify a default export.
This does not affect the JavaScript emitted by TypeScript, it only for the type checking. This option brings the behavior of TypeScript in-line with Babel, where extra code is emitted to make using a default export of a module more ergonomic.
Flag | allowSyntheticDefaultImports | |
Default | module === "system" or esModuleInterop | |
Related | [`esModuleInterop`](#esModuleInterop) | |
Released | 1.8 |
# Es Module Interop - esModuleInterop
Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports.
TypeScript adheres to the EcmaScript standard for modules, which means that a file with exports would have to specifically
include a default
export in order to support syntax like import React from "react"
.
This export pattern is rare in modules for CommonJS. For example, without esModuleInterop
as true:
ts// @filename: utilFunctions.js const getStringLength = str => str.length; moduanymodulemodule export= (property) export=: { getStringLength: (str: any) => any; }.module export= (property) export=: { getStringLength: (str: any) => any; }exports = { getStringLength }; // @filename: index.ts import utils from "./utilFunctions"; const count = utils.getStringLength("Check JS");
This won’t work because there isn’t a default
object which you can import. Even though it feels like it should.
For convenience, transpilers like Babel will automatically create a default if one isn’t created. Making the module look a bit more like:
// @filename: utilFunctions.js
const getStringLength = str => str.length;
const allFunctions = {
getStringLength
};
module.exports = allFunctions;
Turning on this compiler flag will also enable allowSyntheticDefaultImports
.
Flag | esModuleInterop | |
Default | `false` | |
Related | [`allowSyntheticDefaultImports`](#allowSyntheticDefaultImports) | |
Released | 2.7 |
# Preserve Symlinks - preserveSymlinks
This is to reflect the same flag in Node.js; which does not resolve the real path of symlinks.
This flag also exhibits the opposite behavior to Webpack’s resolve.symlinks
option (i.e. setting TypeScript’s preserveSymlinks
to true parallels setting Webpack’s resolve.symlinks
to false, and vice-versa).
With this enabled, references to modules and packages (e.g. import
s and /// <reference type="..." />
directives) are all resolved relative to the location of the symbolic link file, rather than relative to the path that the symbolic link resolves to.
Flag | preserveSymlinks | |
Default | `false` |
# Allow Umd Global Access - allowUmdGlobalAccess
When set to true, allowUmdGlobalAccess
lets you access UMD exports as globals from inside module files. A module file is a file that has imports and/or exports. Without this flag, using an export from a UMD module requires an import declaration.
An example use case for this flag would be a web project where you know the particular library (like jQuery or Lodash) will always be available at runtime, but you can’t access it with an import.
Flag | allowUmdGlobalAccess | |
Default | `false` | |
Released | 3.5 |
# Source Maps
In order to provide rich debugging tools and crash reports which make sense to developers, TypeScript supports emitting additional files which conform to the JavaScript Source Map standards.
These are emitted as .map
files which live alongside the file they represent.
# Source Root - sourceRoot
Specify the location where a debugger should locate TypeScript files instead of relative source locations. This string is treated verbatim inside the source-map where you can use a path or a URL:
{
"compilerOptions": {
"sourceMap": true,
"sourceRoot": "https://my-website.com/debug/source/"
}
}
Would declare that index.js
will have a source file at https://my-website.com/debug/source/index.ts
.
Flag | sourceRoot |
# Map Root - mapRoot
Specify the location where debugger should locate map files instead of generated locations. This string is treated verbatim inside the source-map, for example:
{
"compilerOptions": {
"sourceMap": true,
"mapRoot": "https://my-website.com/debug/sourcemaps/"
}
}
Would declare that index.js
will have sourcemaps at https://my-website.com/debug/sourcemaps/index.js.map
.
Flag | mapRoot |
# Inline Source Map - inlineSourceMap
When set, instead of writing out a .js.map
file to provide source maps, TypeScript will embed the source map content in the .js
files.
Although this results in larger JS files, it can be convenient in some scenarios.
For example, you might want to debug JS files on a webserver that doesn’t allow .map
files to be served.
Mutually exclusive with sourceMap
.
For example, with this TypeScript:
const helloWorld = "hi";
console.log(helloWorld);
Converts to this JavaScript:
js"use strict"; const helloWorld = "hi"; console.log(helloWorld);
Then enable building it with inlineSourceMap
enabled there is a comment at the bottom of the file which includes
a source-map for the file.
js"use strict"; const helloWorld = "hi"; console.log(helloWorld); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDO0FBQ3hCLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMifQ==
Flag | inlineSourceMap | |
Default | `false` | |
Released | 1.5 |
# Inline Sources - inlineSources
When set, TypeScript will include the original content of the .ts
file as an embedded string in the source map.
This is often useful in the same cases as inlineSourceMap
.
Requires either sourceMap
or inlineSourceMap
to be set.
For example, with this TypeScript:
const helloWorld = "hi";
console.log(helloWorld);
By default converts to this JavaScript:
js"use strict"; const helloWorld = "hi"; console.log(helloWorld);
Then enable building it with inlineSources
and inlineSourceMap
enabled there is a comment at the bottom of the file which includes
a source-map for the file.
Note that the end is different from the example in inlineSourceMap
because the source-map now contains the original source code also.
js"use strict"; const helloWorld = "hi"; console.log(helloWorld); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDO0FBQ3hCLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBoZWxsb1dvcmxkID0gXCJoaVwiO1xuY29uc29sZS5sb2coaGVsbG9Xb3JsZCk7Il19
Flag | inlineSources | |
Default | `false` | |
Released | 1.5 |
# Additional Checks
Additional Checks Copy
# No Unused Locals - noUnusedLocals
Report errors on unused local variables.
tsconst createKeyboardconst createKeyboard: (modelID: number) => { type: string; modelID: number; } = (modelID(parameter) modelID: number: number) => { const defaultModelIDconst defaultModelID: 23 = 23; 'defaultModelID' is declared but its value is never read.6133'defaultModelID' is declared but its value is never read. return { type(property) type: string: "keyboard", modelID(property) modelID: number }; };
Flag | noUnusedLocals | |
Default | `false` | |
Released | 2.0 |
# No Unused Parameters - noUnusedParameters
Report errors on unused parameters in functions.
tsconst createDefaultKeyboardconst createDefaultKeyboard: (modelID: number) => { type: string; modelID: number; } = (modelID(parameter) modelID: number: number) => { const defaultModelIDconst defaultModelID: 23 = 23; return { type(property) type: string: "keyboard", modelID(property) modelID: number: defaultModelIDconst defaultModelID: 23 }; };
Flag | noUnusedParameters | |
Default | `false` | |
Released | 2.0 |
# No Implicit Returns - noImplicitReturns
When enabled, TypeScript will check all code paths in a function to ensure they return a value.
tsfunction lookupHeadphonesManufacturerfunction lookupHeadphonesManufacturer(color: "blue" | "black"): string(color(parameter) color: "blue" | "black": "blue" | "black"): string { Function lacks ending return statement and return type does not include 'undefined'.2366Function lacks ending return statement and return type does not include 'undefined'. if (color(parameter) color: "blue" | "black" === "blue") { return "beats"; } else { "bose"; } }
Flag | noImplicitReturns | |
Default | `false`, unless `strict` is set | |
Released | 1.8 |
# No Fallthrough Cases In Switch - noFallthroughCasesInSwitch
Report errors for fallthrough cases in switch statement.
Ensures that any non-empty case inside a switch statement includes either break
or return
.
This means you won’t accidentally ship a case fallthrough bug.
tsconst aconst a: number: number = 6; switch (aconst a: number) { case 0: Fallthrough case in switch.7029Fallthrough case in switch. consolevar console: Console.log(method) Console.log(message?: any, ...optionalParams: any[]): void("even"); case 1: consolevar console: Console.log(method) Console.log(message?: any, ...optionalParams: any[]): void("odd"); break; }
Flag | noFallthroughCasesInSwitch | |
Default | `false` | |
Released | 1.8 |
# Experimental
TypeScript strives to only include features which are confirmed to be added into the JavaScript language.
There have been cases where a feature is compelling enough to be an exception to that rule, and these live as experimental compiler flags. It is possible that a version of these features may be different when/if they are added to the JavaScript language, and thus are considered risky.
# Experimental Decorators - experimentalDecorators
Enables experimental support for decorators, which is in stage 2 of the TC39 standardization process.
Decorators are a language feature which hasn’t yet been fully ratified into the JavaScript specification. This means that the implementation version in TypeScript may differ from the implementation in JavaScript when it it decided by TC39.
You can find out more about decorator support in TypeScript in the handbook.
Flag | experimentalDecorators | |
Related | [`emitDecoratorMetadata`](#emitDecoratorMetadata) |
# Emit Decorator Metadata - emitDecoratorMetadata
Enables experimental support for emitting type metadata for decorators which works with the module reflect-metadata
.
For example, here is the JavaScript
tsfunction LogMethodfunction LogMethod(target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor): void( target(parameter) target: any: any, propertyKey(parameter) propertyKey: string | symbol: string | symbol, descriptor(parameter) descriptor: PropertyDescriptor: PropertyDescriptorinterface PropertyDescriptor ) { consolevar console: Console.log(method) Console.log(message?: any, ...optionalParams: any[]): void(target(parameter) target: any); consolevar console: Console.log(method) Console.log(message?: any, ...optionalParams: any[]): void(propertyKey(parameter) propertyKey: string | symbol); consolevar console: Console.log(method) Console.log(message?: any, ...optionalParams: any[]): void(descriptor(parameter) descriptor: PropertyDescriptor); } class Democlass Demo { @LogMethodfunction LogMethod(target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor): void public foo(method) Demo.foo(bar: number): void(bar(parameter) bar: number: number) { // do nothing } } const democonst demo: Demo = new Democonstructor Demo(): Demo();
With emitDecoratorMetadata
not set to true (default):
js"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; function LogMethod(target, propertyKey, descriptor) { console.log(target); console.log(propertyKey); console.log(descriptor); } class Demo { foo(bar) { // do nothing } } __decorate([ LogMethod ], Demo.prototype, "foo", null); const demo = new Demo();
With emitDecoratorMetadata
set to true:
js"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; function LogMethod(target, propertyKey, descriptor) { console.log(target); console.log(propertyKey); console.log(descriptor); } class Demo { foo(bar) { // do nothing } } __decorate([ LogMethod, __metadata("design:type", Function), __metadata("design:paramtypes", [Number]), __metadata("design:returntype", void 0) ], Demo.prototype, "foo", null); const demo = new Demo();
Flag | emitDecoratorMetadata | |
Related | [`experimentalDecorators`](#experimentalDecorators) |
# Advanced
Flags which help with debugging
# Import Helpers - importHelpers
For certain downleveling operations, TypeScript uses some helper code for operations like extending class, spreading arrays or objects, and async operations. By default, these helpers are inserted into files which use them. This can result in code duplication if the same helper is used in many different modules.
If the importHelpers
flag is on, these helper functions are instead imported from the tslib module.
You will need to ensure that the tslib
module is able to be imported at runtime.
This only affects modules; global script files will not attempt to import modules.
For example, with this TypeScript:
export function fn(arr: number[]) {
const arr2 = [1, ...arr];
}
Turning on downlevelIteration
and importHelpers
is still false:
js"use strict"; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spread = (this && this.__spread) || function () { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; }; Object.defineProperty(exports, "__esModule", { value: true }); function fn(arr) { var arr2 = __spread([1], arr); } exports.fn = fn;
Then turning on both downlevelIteration
and importHelpers
:
js"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); function fn(arr) { var arr2 = tslib_1.__spread([1], arr); } exports.fn = fn;
You can use noEmitHelpers
when you provide your own implementations of these functions.
Flag | importHelpers | |
Default | `false` |
# List Files - listFiles
Print names of files part of the compilation. This is useful when you are not sure that TypeScript has included a file you expected.
For example:
example
├── index.ts
├── package.json
└── tsconfig.json
With:
{
"compilerOptions": {
"listFiles": true
}
}
Would echo paths like:
$ npm run tsc
path/to/example/node_modules/typescript/lib/lib.d.ts
path/to/example/node_modules/typescript/lib/lib.es5.d.ts
path/to/example/node_modules/typescript/lib/lib.dom.d.ts
path/to/example/node_modules/typescript/lib/lib.webworker.importscripts.d.ts
path/to/example/node_modules/typescript/lib/lib.scripthost.d.ts
path/to/example/index.ts
Flag | listFiles | |
Default | `false` |
# List Emitted Files - listEmittedFiles
Print names of generated files part of the compilation to the terminal.
This flag is useful in two cases:
- You want to transpile TypeScript as a part of a build chain in the terminal where the filenames are processed in the next command.
- You are not sure that TypeScript has included a file you expected, as a part of debugging the file inclusion settings.
For example:
example
├── index.ts
├── package.json
└── tsconfig.json
With:
{
"compilerOptions": {
"declaration": true,
"listFiles": true
}
}
Would echo paths like:
$ npm run tsc
path/to/example/index.js
path/to/example/index.d.ts
Normally, TypeScript would return silently on success.
Flag | listEmittedFiles | |
Default | `false` |
# Trace Resolution - traceResolution
When you are trying to debug why a module isn’t being included.
You can set traceResolutions
to true
to have TypeScript print information about its resolution process for each processed file.
You can read more about this in the handbook.
Flag | traceResolution | |
Default | `false` | |
Released | 2.0 |
# Diagnostics - diagnostics
Used to output diagnostic information for debugging. This command is a subset of extendedDiagnostics
which are more user-facing results, and easier to interpret.
If you have been asked by a TypeScript compiler engineer to give the results using this flag in a compile, in which there is no harm in using --extendedDiagnostics
instead.
Flag | diagnostics | |
Status | Deprecated | |
Default | `false` | |
Related | [`extendedDiagnostics`](#extendedDiagnostics) | |
Status | Deprecated |
# Extended Diagnostics - extendedDiagnostics
You can use this flag to discover where TypeScript is spending it’s time when compiling. This is a tool used for understanding the performance characteristics of your codebase overall.
You can learn more about how to measure and understand the output in the performance section of the wiki.
Flag | extendedDiagnostics | |
Default | `false` | |
Related | [`diagnostics`](#diagnostics) |
# Generate CPU Profile - generateCpuProfile
This option gives you the chance to have TypeScript emit a v8 CPU profile during the compiler run. The CPU profile can provide insight into why your builds may be slow.
This option can only be used from the CLI via: --generateCpuProfile tsc-output.cpuprofile
.
npm run tsc --generateCpuProfile tsc-output.cpuprofile
This file can be opened in a chromium based browser like Chrome or Edge Developer in the CPU profiler section. You can learn more about understanding the compilers performance in the TypeScript wiki section on performance.
Flag | generateCpuProfile | |
Default | profile.cpuprofile | |
Released | 3.7 |
# Emit Declaration Only - emitDeclarationOnly
Only emit .d.ts
files; do not emit .js
files.
This setting is useful in two cases:
- You are using a transpiler other than TypeScript to generate your JavaScript.
- You are using TypeScript to only generate
d.ts
files for your consumers.
Flag | emitDeclarationOnly | |
Default | `false` | |
Released | 2.8 |
# JSX Factory - jsxFactory
Changes the function called in .js
files when compiling JSX Elements.
The most common change is to use "h"
or "preact.h"
instead of the default "React.createElement"
if using preact
.
This is the same as Babel’s /** @jsx h */
directive.
Flag | jsxFactory | |
Default | `React"` | |
Allowed | **Allowed Values**: Any identifier or dotted identifier; default `"React.createElement"` |
# Resolve JSON Module - resolveJsonModule
Allows importing modules with a ‘.json’ extension, which is a common practice in node projects. This includes
generating a type for the import
based on the static JSON shape.
TypeScript does not support resolving JSON files by default:
// @filename: settings.json
{
"repo": "TypeScript",
"dry": false,
"debug": false
}
// @filename: index.ts
import settings from "./settings.json";
settings.debug === true;
settings.dry === 2;
Enabling the option allows importing JSON, and validating the types in that JSON file.
// @filename: settings.json
{
"repo": "TypeScript",
"dry": false,
"debug": false
}
// @filename: index.ts
import settings from "./settings.json";
settings.debug === true;
settings.dry === 2;
Flag | resolveJsonModule | |
Default | `false` |
# Out - out
Use outFile instead.
The out
option computes the final file location in a way that is not predictable or consistent.
This option is retained for backward compatibility only and is deprecated.
Flag | out | |
Status | Deprecated | |
Default | `n/a` | |
Related | [`outDir`](#outDir), [`outFile`](#outFile) | |
Status | Deprecated |
# React Namespace - reactNamespace
Use --jsxFactory
instead. Specify the object invoked for createElement
when targeting react
for TSX files.
Flag | reactNamespace | |
Default | `"React"` |
# Skip Default Lib Check - skipDefaultLibCheck
Use --skipLibCheck
instead. Skip type checking of default library declaration files.
Flag | skipDefaultLibCheck | |
Default | `false` |
# Charset - charset
In prior versions of TypeScript, this controlled what encoding was used when reading text files from disk. Today, TypeScript assumes UTF-8 encoding, but will correctly detect UTF-16 (BE and LE) or UTF-8 BOMs.
Flag | charset | |
Status | Deprecated | |
Default | `utf8` | |
Status | Deprecated |
# Emit BOM - emitBOM
Controls whether TypeScript will emit a byte order mark (BOM) when writing output files.
Some runtime environments require a BOM to correctly interpret a JavaScript files; others require that it is not present.
The default value of false
is generally best unless you have a reason to change it.
Flag | emitBOM | |
Default | `false` |
# New Line - newLine
Specify the end of line sequence to be used when emitting files: ‘CRLF’ (dos) or ‘LF’ (unix).
Flag | newLine | |
Default | Platform specific | |
Released | 1.5 |
# No Error Truncation - noErrorTruncation
TODO: Declare deprecated?!
Do not truncate error messages.
With false
tsvar xvar x: { propertyWithAnExceedinglyLongName1: string; propertyWithAnExceedinglyLongName2: string; propertyWithAnExceedinglyLongName3: string; propertyWithAnExceedinglyLongName4: string; propertyWithAnExceedinglyLongName5: string; }: { propertyWithAnExceedinglyLongName1(property) propertyWithAnExceedinglyLongName1: string: string; propertyWithAnExceedinglyLongName2(property) propertyWithAnExceedinglyLongName2: string: string; propertyWithAnExceedinglyLongName3(property) propertyWithAnExceedinglyLongName3: string: string; propertyWithAnExceedinglyLongName4(property) propertyWithAnExceedinglyLongName4: string: string; propertyWithAnExceedinglyLongName5(property) propertyWithAnExceedinglyLongName5: string: string; }; // String representation of type of 'x' should be truncated in error message var svar s: string: string = xvar x: { propertyWithAnExceedinglyLongName1: string; propertyWithAnExceedinglyLongName2: string; propertyWithAnExceedinglyLongName3: string; propertyWithAnExceedinglyLongName4: string; propertyWithAnExceedinglyLongName5: string; }; Type '{ propertyWithAnExceedinglyLongName1: string; propertyWithAnExceedinglyLongName2: string; propertyWithAnExceedinglyLongName3: string; propertyWithAnExceedinglyLongName4: string; propertyWithAnExceedinglyLongName5: string; }' is not assignable to type 'string'.Variable 'x' is used before being assigned.2322
2454Type '{ propertyWithAnExceedinglyLongName1: string; propertyWithAnExceedinglyLongName2: string; propertyWithAnExceedinglyLongName3: string; propertyWithAnExceedinglyLongName4: string; propertyWithAnExceedinglyLongName5: string; }' is not assignable to type 'string'.Variable 'x' is used before being assigned.
With true
tsvar xvar x: { propertyWithAnExceedinglyLongName1: string; propertyWithAnExceedinglyLongName2: string; propertyWithAnExceedinglyLongName3: string; propertyWithAnExceedinglyLongName4: string; propertyWithAnExceedinglyLongName5: string; }: { propertyWithAnExceedinglyLongName1(property) propertyWithAnExceedinglyLongName1: string: string; propertyWithAnExceedinglyLongName2(property) propertyWithAnExceedinglyLongName2: string: string; propertyWithAnExceedinglyLongName3(property) propertyWithAnExceedinglyLongName3: string: string; propertyWithAnExceedinglyLongName4(property) propertyWithAnExceedinglyLongName4: string: string; propertyWithAnExceedinglyLongName5(property) propertyWithAnExceedinglyLongName5: string: string; }; // String representation of type of 'x' should be truncated in error message var svar s: string: string = xvar x: { propertyWithAnExceedinglyLongName1: string; propertyWithAnExceedinglyLongName2: string; propertyWithAnExceedinglyLongName3: string; propertyWithAnExceedinglyLongName4: string; propertyWithAnExceedinglyLongName5: string; }; Type '{ propertyWithAnExceedinglyLongName1: string; propertyWithAnExceedinglyLongName2: string; propertyWithAnExceedinglyLongName3: string; propertyWithAnExceedinglyLongName4: string; propertyWithAnExceedinglyLongName5: string; }' is not assignable to type 'string'.Variable 'x' is used before being assigned.2322
2454Type '{ propertyWithAnExceedinglyLongName1: string; propertyWithAnExceedinglyLongName2: string; propertyWithAnExceedinglyLongName3: string; propertyWithAnExceedinglyLongName4: string; propertyWithAnExceedinglyLongName5: string; }' is not assignable to type 'string'.Variable 'x' is used before being assigned.
Flag | noErrorTruncation | |
Status | Deprecated | |
Default | `false` | |
Status | Deprecated |
# No Lib - noLib
Disables the automatic inclusion of any library files.
If this option is set, lib
is ignored.
Flag | noLib | |
Default | `false` |
# No Resolve - noResolve
By default, TypeScript will examine the initial set of files for import
and <reference
directives and add these resolved files to your program.
If noResolve
isn’t set, this process doesn’t happen.
However, import
statements are still checked to see if they resolve to a valid module, so you’ll need to make sure this is satisfied by some other means.
Flag | noResolve | |
Default | `false` |
# Strip Internal - stripInternal
Do not emit declarations for code that has an @internal
annotation in it’s JSDoc comment.
This is an internal compiler option; use at your own risk, because the compiler does not check that the result is valid.
If you are searching for a tool to handle additional levels of visibility within your d.ts
files, look at api-extractor.
ts/** * Days available in a week * @internal */ export const daysInAWeekconst daysInAWeek: 7 = 7; /** Gets the */ export function weeklySalaryfunction weeklySalary(dayRate: number): number(dayRate(parameter) dayRate: number: number) { return daysInAWeekconst daysInAWeek: 7 * dayRate(parameter) dayRate: number; }
With the flag set to false
(default):
ts/** * Days available in a week * @internal */ export declare const daysInAWeek = 7; /** Calculate how much someone earns in a week */ export declare function weeklySalary(dayRate: number): number;
With stripInternal
set to true
the d.ts
emitted will be redacted.
ts/** Calculate how much someone earns in a week */ export declare function weeklySalary(dayRate: number): number;
The JavaScript output is still the same.
Flag | stripInternal | |
Status | internal |
# Disable Size Limit - disableSizeLimit
To avoid a possible memory bloat issue when working with very large JavaScript projects, there is an upper limit to the amount of memory TypeScript will allocate. Turning this flag on will remove the limit.
Flag | disableSizeLimit | |
Default | `false` |
# Disable Source Project Reference Redirect - disableSourceOfProjectReferenceRedirect
When working with composite TypeScript projects, this option provides a way to go back to the pre-3.7 behavior where d.ts files were used to as the boundaries between modules. In 3.7 the source of truth is now your TypeScript files.
Flag | disableSourceOfProjectReferenceRedirect | |
Released | 3.7 |
# No Implicit Use Strict - noImplicitUseStrict
You shouldn’t need this. By default, when emitting a module file to a non-ES6 target, TypeScript emits a "use strict";
prologue at the top of the file.
This setting disables the prologue.
jsdefine(["require", "exports"], function (require, exports) { "use strict"; exports.__esModule = true; function fn() { } exports.fn = fn; });
jsdefine(["require", "exports"], function (require, exports) { "use strict"; exports.__esModule = true; function fn() { } exports.fn = fn; });
Flag | noImplicitUseStrict | |
Default | `false` |
# No Emit Helpers - noEmitHelpers
Instead of importing helpers with importHelpers
, you can provide implementations in the global scope for the helpers you use and completely turn off emitting of helper functions.
For example, using this async
function in ES5 requires a await
-like function and generator
-like function to run:
tsconst getAPIconst getAPI: (url: string) => Promise<{}> = async (url(parameter) url: string: string) => { // Get API return {}; };
Which creates quite a lot of JavaScript:
js"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var getAPI = function (url) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { // Get API return [2 /*return*/, {}]; }); }); };
Which can be switched out with your own globals via this flag:
js"use strict"; var getAPI = function (url) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { // Get API return [2 /*return*/, {}]; }); }); };
Flag | noEmitHelpers | |
Default | `false` | |
Related | [`importHelpers`](#importHelpers) | |
Released | 1.5 |
# No Emit On Error - noEmitOnError
Do not emit compiler output files like JavaScript source code, source-maps or declarations if any errors were reported.
This defaults to false
, making it easier to work with TypeScript in a watch-like environment where you may want to see results of changes to your code in another environment before making sure all errors are resolved.
Flag | noEmitOnError | |
Default | `false` | |
Released | 1.4 |
# Preserve Const Enums - preserveConstEnums
Do not erase const enum
declarations in generated code. const enum
s provide a way to reduce the overall memory footprint
of your application at runtime by emitting the enum value instead of a reference.
For example with this TypeScript:
tsconst enum Albumconst enum Album { JimmyEatWorldFutures(enum member) Album.JimmyEatWorldFutures = 1 = 1, TubRingZooHypothesis(enum member) Album.TubRingZooHypothesis = 2 = 2, DogFashionDiscoAdultery(enum member) Album.DogFashionDiscoAdultery = 3 = 3 } const selectedAlbumconst selectedAlbum: Album.JimmyEatWorldFutures = Albumconst enum Album.JimmyEatWorldFutures(enum member) Album.JimmyEatWorldFutures = 1; if (selectedAlbumconst selectedAlbum: Album.JimmyEatWorldFutures === Albumconst enum Album.JimmyEatWorldFutures(enum member) Album.JimmyEatWorldFutures = 1) { consolevar console: Console.log(method) Console.log(message?: any, ...optionalParams: any[]): void("That is a great choice."); }
The default const enum
behavior is to convert any Album.Something
to the corresponding number literal, and to remove a reference
to the enum from the JavaScript completely.
js"use strict"; const selectedAlbum = 1 /* JimmyEatWorldFutures */; if (selectedAlbum === 1 /* JimmyEatWorldFutures */) { console.log("That is a great choice."); }
With preserveConstEnums
set to true
, the enum
exists at runtime and the numbers are still emitted.
js"use strict"; var Album; (function (Album) { Album[Album["JimmyEatWorldFutures"] = 1] = "JimmyEatWorldFutures"; Album[Album["TubRingZooHypothesis"] = 2] = "TubRingZooHypothesis"; Album[Album["DogFashionDiscoAdultery"] = 3] = "DogFashionDiscoAdultery"; })(Album || (Album = {})); const selectedAlbum = 1 /* JimmyEatWorldFutures */; if (selectedAlbum === 1 /* JimmyEatWorldFutures */) { console.log("That is a great choice."); }
This essentially makes such const enums
a source-code feature only, with no runtime traces.
Flag | preserveConstEnums | |
Default | `false` |
# Declaration Dir - declarationDir
Offers a way to configure the root directory for where declaration files are emitted.
example
├── index.ts
├── package.json
└── tsconfig.json
with this tsconfig.json
:
{
"compilerOptions": {
"declaration": true,
"declarationDir": "./types"
}
}
Would place the d.ts for the index.ts
in a types
folder:
example
├── index.js
├── index.ts
├── package.json
├── tsconfig.json
└── types
└── index.d.ts
Flag | declarationDir | |
Default | n/a | |
Released | 2.0 |
# Skip Lib Check - skipLibCheck
Skip type checking of declaration files.
This can save time during compilation at the expense of type-system accuracy. For example, two libraries could
define two copies of the same type
in an inconsistent way. Rather than doing a full check of all d.ts
files, TypeScript
will type check the code you specifically refer to in your app’s source code.
A common case where you might think to use skipLibCheck
is when there are two copies of a library’s types in
your node_modules
. In these cases, you should consider using a feature like yarn’s resolutions
to ensure there is only one copy of that dependency in your tree or investigate how to ensure there is
only one copy by understanding the dependency resolution to fix the issue without additional tooling.
Flag | skipLibCheck | |
Default | `false` | |
Released | 2.0 |
# Allow Unused Labels - allowUnusedLabels
Set to false to disable warnings about unused labels.
Labels are very rare in JavaScript and typically indicate an attempt to write an object literal:
tsfunction verifyAgefunction verifyAge(age: number): void(age(parameter) age: number: number) { // Forgot 'return' statement if (age(parameter) age: number > 18) { verified: true; Unused label.7028Unused label. } }
Flag | allowUnusedLabels | |
Default | `false` | |
Released | 1.8 |
# Allow Unreachable Code - allowUnreachableCode
Set to false to disable warnings about unreachable code. These warnings are only about code which is provably unreachable due to the use of JavaScript syntax, for example:
function fn(n: number) {
if (n > 5) {
return true;
} else {
return false;
}
return true;
}
With "allowUnreachableCode": false
:
tsfunction fnfunction fn(n: number): boolean(n(parameter) n: number: number) { if (n(parameter) n: number > 5) { return true; } else { return false; } return true; Unreachable code detected.7027Unreachable code detected.}
This does not affect errors on the basis of code which appears to be unreachable due to type analysis.
Flag | allowUnreachableCode | |
Default | `false` | |
Released | 1.8 |
# Suppress Excess Property Errors - suppressExcessPropertyErrors
This disables reporting of excess property errors, such as the one shown in the following example:
tstype Pointtype Point = { x: number; y: number; } = { x(property) x: number: number; y(property) y: number: number }; const pconst p: Point: Pointtype Point = { x: number; y: number; } = { x(property) x: number: 1, y(property) y: number: 3, m(property) m: number: 10 }; Type '{ x: number; y: number; m: number; }' is not assignable to type 'Point'. Object literal may only specify known properties, and 'm' does not exist in type 'Point'.2322Type '{ x: number; y: number; m: number; }' is not assignable to type 'Point'. Object literal may only specify known properties, and 'm' does not exist in type 'Point'.
This flag was added to help people migrate to the stricter checking of new object literals in TypeScript 1.6.
We don’t recommend using this flag in a modern codebase, you can suppress one-off cases where you need it using // @ts-ignore
.
Flag | suppressExcessPropertyErrors | |
Default | `false` |
# Suppress Implicit Any Index Errors - suppressImplicitAnyIndexErrors
Turning noImplicitAny
on suppresses implicit any warning reports when indexing into objects, as shown in the following example:
tsconst objconst obj: { x: number; } = { x(property) x: number: 10 }; consolevar console: Console.log(method) Console.log(message?: any, ...optionalParams: any[]): void(objconst obj: { x: number; }["foo"]); Element implicitly has an 'any' type because expression of type '"foo"' can't be used to index type '{ x: number; }'. Property 'foo' does not exist on type '{ x: number; }'.7053Element implicitly has an 'any' type because expression of type '"foo"' can't be used to index type '{ x: number; }'. Property 'foo' does not exist on type '{ x: number; }'.
Using suppressImplicitAnyIndexErrors
is quite a drastic approach. It is recommended to use a @ts-ignore
comment instead:
tsconst objconst obj: { x: number; } = { x(property) x: number: 10 }; // @ts-ignore consolevar console: Console.log(method) Console.log(message?: any, ...optionalParams: any[]): void(objconst obj: { x: number; }["foo"]);
Flag | suppressImplicitAnyIndexErrors | |
Default | `false` |
# Force Consistent Casing In File Names - forceConsistentCasingInFileNames
TypeScript follows the case sensitivity rules of the file system it’s running on.
This can be problematic if some developers are working in a case-sensitive file system and others aren’t.
If a file attempts to import fileManager.ts
by specifying ./FileManager.ts
the file will be found in a case-insensitive file system, but not on a case-sensitive file system.
When this option is set, TypeScript will issue an error if a program tries to include a file by a casing different from the casing on disk.
Flag | forceConsistentCasingInFileNames | |
Recommended | True | |
Default | `false` |
# Max Node Module JS Depth - maxNodeModuleJsDepth
The maximum dependency depth to search under node_modules
and load JavaScript files.
This flag is can only be used when allowJs
is enabled, and is used if you want to have TypeScript infer types for all of the JavaScript inside your node_modules
.
Ideally this should stay at 0 (the default), and d.ts
files should be used to explicitly define the shape of modules.
However, there are cases where you may want to turn this on at the expense of speed and potential accuracy.
Flag | maxNodeModuleJsDepth | |
Default | `0` |
# No Strict Generic Checks - noStrictGenericChecks
Disable strict checking of generic signatures in function types.
Flag | noStrictGenericChecks | |
Default | `false` |
# Use Define For Class Fields - useDefineForClassFields
This flag is used as part of migrating to the upcoming standard version of class fields. TypeScript introduced class fields many years before it was ratified in TC39. The latest version of the upcoming specification has a different runtime behavior to TypeScript’s implementation but the same syntax.
This flag switches to the upcoming ECMA runtime behavior.
You can read more about the transition in the 3.7 release notes.
Flag | useDefineForClassFields | |
Released | 3.7 |
# Keyof Strings Only - keyofStringsOnly
This flag changes the keyof
type operator to return string
instead of string | number
when applied to a type with a string index signature.
This flag is used to help people keep this behavior from before TypeScript 2.9’s release.
Flag | keyofStringsOnly | |
Status | Deprecated | |
Default | `false` | |
Status | Deprecated | |
Released | 2.9 |
# Command Line
# Preserve Watch Output - preserveWatchOutput
Whether to keep outdated console output in watch mode instead of clearing the screen every time a change happened.
Flag | preserveWatchOutput | |
Default | `false` | |
Status | internal |
# Pretty - pretty
Stylize errors and messages using color and context, this is on by default — offers you a chance to have less terse, single colored messages from the compiler.
Flag | pretty | |
Default | `true` |