Skip to content
Your logo here
Your logo here
Your logo here
Your logo here
Your logo here
Your logo here
Your logo here
Your logo here
Your logo here
Your logo here
Your logo here
Your logo here
Your logo here
Your logo here
Your logo here
Your logo here
Your logo here
Your logo here

Emit

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:

ts
export let 
helloWorld
= "hi";
Try

Will generate an index.js file like this:

ts
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.helloWorld = void 0;
exports.helloWorld = "hi";
Try

With a corresponding helloWorld.d.ts:

ts
export declare let helloWorld: string;
Try

When working with .d.ts files for JavaScript files you may want to use emitDeclarationOnly or use outDir to ensure that the JavaScript files are not overwritten.

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:

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

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.

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

With this TypeScript code:

ts
const 
str
= "Hello!";
for (const
s
of
str
) {
console
.
log
(
s
);
}
Try

Without downlevelIteration enabled, a for / of loop on any object is downleveled to a traditional for loop:

ts
"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);
}
Try

This is often what people expect, but it's not 100% compliant with ECMAScript iteration protocol. 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.

ts
"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; }
}
Try

You can use tslib via importHelpers to reduce the amount of inline JavaScript too:

ts
"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; }
}
Try

Note: enabling downlevelIteration does not improve compliance if Symbol.iterator is not present in the runtime.

Example: Effects on Array Spreads

This is an array spread:

js
// Make a new array whose elements are 1 followed by the elements of arr2
const arr = [1, ...arr2];

Based on the description, it sounds easy to downlevel to ES5:

js
// The same, right?
const arr = [1].concat(arr2);

However, this is observably different in certain rare cases.

For example, if a source array is missing one or more items (contains a hole), the spread syntax will replace each empty item with undefined, whereas .concat will leave them intact.

js
// Make an array where the element at index 1 is missing
let arrayWithHole = ['a', , 'c'];
let spread = [...arrayWithHole];
let concatenated = [].concat(arrayWithHole);

console.log(arrayWithHole)
// [ 'a', <1 empty item>, 'c' ]
console.log(spread)
// [ 'a', undefined, 'c' ]
console.log(concatenated)
// [ 'a', <1 empty item>, 'c' ]

Just as with for / of, downlevelIteration will use Symbol.iterator (if present) to more accurately emulate ES 6 behavior.

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.

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.

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:

ts
export function fn(arr: number[]) {
  const arr2 = [1, ...arr];
}

Turning on downlevelIteration and importHelpers is still false:

ts
"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 __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.fn = fn;
function fn(arr) {
    var arr2 = __spreadArray([1], __read(arr), false);
}
Try

Then turning on both downlevelIteration and importHelpers:

ts
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.fn = fn;
var tslib_1 = require("tslib");
function fn(arr) {
    var arr2 = tslib_1.__spreadArray([1], tslib_1.__read(arr), false);
}
Try

You can use noEmitHelpers when you provide your own implementations of these functions.

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:

ts
const helloWorld = "hi";
console.log(helloWorld);

Converts to this JavaScript:

ts
"use strict";
const helloWorld = "hi";
console.log(helloWorld);
Try

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.

ts
"use strict";
const helloWorld = "hi";
console.log(helloWorld);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDO0FBQ3hCLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMifQ==
Try

inlineSources

When set, TypeScript will include the original content of the .ts file as an embedded string in the source map (using the source map's sourcesContent property). This is often useful in the same cases as inlineSourceMap.

Requires either sourceMap or inlineSourceMap to be set.

For example, with this TypeScript:

ts
const 
helloWorld
= "hi";
console
.
log
(
helloWorld
);
Try

By default converts to this JavaScript:

ts
"use strict";
const helloWorld = "hi";
console.log(helloWorld);
Try

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.

ts
"use strict";
const helloWorld = "hi";
console.log(helloWorld);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDO0FBQ3hCLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBoZWxsb1dvcmxkID0gXCJoaVwiO1xuY29uc29sZS5sb2coaGVsbG9Xb3JsZCk7Il19
Try

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:

json
{
  "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.

newLine

  • Allowed: crlf,lf

  • Default: lf

  • Released: 1.5

Specify the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix).

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.

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:

ts
const 
getAPI
= async (
url
: string) => {
// Get API return {}; };
Try

Which creates quite a lot of JavaScript:

ts
"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 = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
    return g.next = verb(0), g["throw"] = verb(1), g["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 (g && (g = 0, op[0] && (_ = 0)), _) 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*/, {}];
    });
}); };
Try

Which can be switched out with your own globals via this flag:

ts
"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*/, {}];
    });
}); };
Try

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.

outDir

If specified, .js (as well as .d.ts, .js.map, etc.) files will be emitted into this 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:

sh
$ tsc

example
├── index.js
└── index.ts

With a tsconfig.json like this:

json
{
  "compilerOptions": {
    "outDir": "dist"
  }
}

Running tsc with these settings moves the files into the specified dist folder:

sh
$ tsc

example
├── dist
   └── index.js
├── index.ts
└── tsconfig.json

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.

preserveConstEnums

Do not erase const enum declarations in generated code. const enums 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:

ts
const enum 
Album
{
JimmyEatWorldFutures
= 1,
TubRingZooHypothesis
= 2,
DogFashionDiscoAdultery
= 3,
} const
selectedAlbum
=
Album
.
JimmyEatWorldFutures
;
if (
selectedAlbum
===
Album
.
JimmyEatWorldFutures
) {
console
.
log
("That is a great choice.");
}
Try

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.

ts
"use strict";
const selectedAlbum = 1 /* Album.JimmyEatWorldFutures */;
if (selectedAlbum === 1 /* Album.JimmyEatWorldFutures */) {
    console.log("That is a great choice.");
}
Try

With preserveConstEnums set to true, the enum exists at runtime and the numbers are still emitted.

ts
"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 /* Album.JimmyEatWorldFutures */;
if (selectedAlbum === 1 /* Album.JimmyEatWorldFutures */) {
    console.log("That is a great choice.");
}
Try

This essentially makes such const enums a source-code feature only, with no runtime traces.

removeComments

Strips all comments from TypeScript files when converting into JavaScript. Defaults to false.

For example, this is a TypeScript file which has a JSDoc comment:

ts
/** The translation of 'Hello world' into Portuguese */
export const helloWorldPTBR = "Olá Mundo";

When removeComments is set to true:

ts
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.helloWorldPTBR = void 0;
exports.helloWorldPTBR = "Olá Mundo";
Try

Without setting removeComments or having it as false:

ts
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.helloWorldPTBR = void 0;
/** The translation of 'Hello world' into Portuguese */
exports.helloWorldPTBR = "Olá Mundo";
Try

This means that your comments will show up in the JavaScript code.

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 where the files are to external tools, for example:

ts
// helloWorld.ts
export declare const helloWorld = "hi";

Compiling with sourceMap set to true creates the following JavaScript file:

js
// helloWorld.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.helloWorld = "hi";
//# sourceMappingURL=// helloWorld.js.map

And this also generates this json map:

json
// helloWorld.js.map
{
  "version": 3,
  "file": "ex.js",
  "sourceRoot": "",
  "sources": ["../ex.ts"],
  "names": [],
  "mappings": ";;AAAa,QAAA,UAAU,GAAG,IAAI,CAAA"
}

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:

json
{
  "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.

stripInternal Internal

Do not emit declarations for code that has an @internal annotation in its 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 
daysInAWeek
= 7;
/** Calculate how much someone earns in a week */ export function
weeklySalary
(
dayRate
: number) {
return
daysInAWeek
*
dayRate
;
}
Try

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;
Try

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;
Try

The JavaScript output is still the same.