Skip to content
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待

输出

declaration

为项目中的每个 TypeScript 或 JavaScript 文件生成 .d.ts 文件。 这些 .d.ts 文件是描述模块外部 API 的类型定义文件。 有了 .d.ts 文件,像 TypeScript 这样的工具可以为无类型代码提供智能感知和准确的类型。

declaration 设置为 true 时,使用此 TypeScript 代码运行编译器:

ts
export let 
helloWorld
= "hi";
Try

将生成一个如下的 index.js 文件:

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

以及对应的 helloWorld.d.ts

ts
export declare let helloWorld: string;
Try

当处理 JavaScript 文件的 .d.ts 文件时,你可能希望使用 emitDeclarationOnly 或使用 outDir 来确保 JavaScript 文件不会被覆盖。

declarationDir

提供一种配置声明文件输出根目录的方法。

example
├── index.ts
├── package.json
└── tsconfig.json

使用此 tsconfig.json

json
{
  "compilerOptions": {
    "declaration": true,
    "declarationDir": "./types"
  }
}

会将 index.ts 的 d.ts 文件放置在 types 文件夹中:

example
├── index.js
├── index.ts
├── package.json
├── tsconfig.json
└── types
    └── index.d.ts

declarationMap

  • 发布版本: 2.9

.d.ts 文件生成源映射,映射回原始的 .ts 源文件。 这将允许像 VS Code 这样的编辑器在使用“转到定义”等功能时跳转到原始的 .ts 文件。

如果你正在使用项目引用,强烈建议你开启此选项。

downlevelIteration

降级是 TypeScript 将代码转译为旧版 JavaScript 的术语。 此标志旨在支持更准确地实现现代 JavaScript 在旧版 JavaScript 运行时中如何迭代新概念。

ECMAScript 6 添加了几个新的迭代原语:for / of 循环 (for (el of arr))、数组展开 ([a, ...b])、参数展开 (fn(...args)) 和 Symbol.iterator。 如果存在 Symbol.iterator 实现,downlevelIteration 允许这些迭代原语在 ES5 环境中被更准确地使用。

示例:对 for / of 的影响

使用此 TypeScript 代码:

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

如果未启用 downlevelIteration,任何对象上的 for / of 循环都会降级为传统的 for 循环:

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

这通常是人们期望的,但它并不 100% 符合 ECMAScript 迭代协议。 某些字符串,如表情符号 (😜),具有 .length 为 2(甚至更多),但在 for-of 循环中应作为 1 个单位迭代。 有关更长的解释,请参阅 Jonathan New 的这篇博文

当启用 downlevelIteration 时,TypeScript 将使用一个辅助函数来检查是否存在 Symbol.iterator 实现(原生或 polyfill)。 如果缺少此实现,将回退到基于索引的迭代。

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

你也可以通过 importHelpers 使用 tslib 来减少内联 JavaScript 的数量:

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

注意: 如果运行时中没有 Symbol.iterator,启用 downlevelIteration 并不会提高合规性。

示例:对数组展开的影响

这是一个数组展开:

js
// 创建一个新数组,其元素为 1 后跟 arr2 的元素
const arr = [1, ...arr2];

根据描述,将其降级到 ES5 似乎很简单:

js
// 相同,对吧?
const arr = [1].concat(arr2);

然而,在少数罕见情况下,这是可观察到的不同。

例如,如果源数组缺少一个或多个项目(包含空位),展开语法会将每个空项替换为 undefined,而 .concat 会保留它们不变。

js
// 创建一个索引 1 处缺失的数组
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' ]

for / of 一样,downlevelIteration 将使用 Symbol.iterator(如果存在)来更准确地模拟 ES6 行为。

emitBOM

  • 发布版本: 1.0

控制 TypeScript 在写入输出文件时是否输出字节顺序标记 (BOM)。 某些运行时环境需要 BOM 才能正确解释 JavaScript 文件;其他运行时则要求不能存在 BOM。 除非你有理由更改它,否则默认值 false 通常是最好的。

emitDeclarationOnly

输出 .d.ts 文件;不输出 .js 文件。

此设置有两种情况下很有用:

  • 你使用 TypeScript 以外的转译器来生成 JavaScript。
  • 你使用 TypeScript 仅为消费者生成 d.ts 文件。

importHelpers

对于某些降级操作,TypeScript 会使用一些辅助代码,例如用于扩展类、展开数组或对象以及异步操作。 默认情况下,这些辅助函数会插入到使用它们的文件中。 如果同一个辅助函数在许多不同的模块中使用,这可能导致代码重复。

如果 importHelpers 标志开启,这些辅助函数将改为从 tslib 模块导入。 你需要确保在运行时可以导入 tslib 模块。 这仅影响模块;全局脚本文件不会尝试导入模块。

例如,使用此 TypeScript:

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

开启 downlevelIterationimportHelpers 仍为 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

然后同时开启 downlevelIterationimportHelpers

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

当你提供这些函数的自己的实现时,可以使用 noEmitHelpers

inlineSourceMap

  • 发布版本: 1.5

设置后,TypeScript 不会写出 .js.map 文件来提供源映射,而是将源映射内容嵌入到 .js 文件中。 虽然这会导致 JS 文件变大,但在某些场景下可能很方便。 例如,你可能想要在不允许提供 .map 文件的 Web 服务器上调试 JS 文件。

sourceMap 互斥。

例如,使用此 TypeScript:

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

转换为以下 JavaScript:

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

然后启用 inlineSourceMap 进行构建时,文件底部会有一个包含源映射的注释。

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

inlineSources

  • 发布版本: 1.5

设置后,TypeScript 会将 .ts 文件的原始内容作为嵌入字符串包含在源映射中(使用源映射的 sourcesContent 属性)。 这在与 inlineSourceMap 相同的情况下通常很有用。

需要设置 sourceMapinlineSourceMap

例如,使用此 TypeScript:

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

默认转换为以下 JavaScript:

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

然后启用 inlineSourcesinlineSourceMap 进行构建时,文件底部会有一个包含源映射的注释。 注意,结尾与 inlineSourceMap 示例不同,因为源映射现在也包含了原始源代码。

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

mapRoot

  • 发布版本: 1.0

指定调试器应定位映射文件的位置,而不是生成的位置。 此字符串在源映射中会被原样使用,例如:

json
{
  "compilerOptions": {
    "sourceMap": true,
    "mapRoot": "https://my-website.com/debug/sourcemaps/"
  }
}

将声明 index.js 的源映射位于 https://my-website.com/debug/sourcemaps/index.js.map

newLine

  • 允许的值: crlf,lf

  • 默认值: lf

  • 发布版本: 1.5

指定输出文件时使用的行尾序列:'CRLF' (dos) 或 'LF' (unix)。

noEmit

  • 发布版本: 1.5

不输出编译器输出文件,如 JavaScript 源代码、源映射或声明文件。

这为另一个工具(如 Babelswc)处理将 TypeScript 文件转换为可在 JavaScript 环境中运行的文件提供了空间。

然后你可以将 TypeScript 用作提供编辑器集成和源代码类型检查的工具。

noEmitHelpers

与使用 importHelpers 导入辅助函数不同,你可以为你使用的辅助函数在全局作用域中提供实现,并完全关闭辅助函数的输出。

例如,在 ES5 中使用此 async 函数需要一个类似 await 的函数和一个类似 generator 的函数来运行:

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

这会生成相当多的 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) {
        // 获取 API
        return [2 /*return*/, {}];
    });
}); };
Try

通过此标志,可以使用你自己的全局变量来替换它们:

ts
"use strict";
var getAPI = function (url) { return __awaiter(void 0, void 0, void 0, function () {
    return __generator(this, function (_a) {
        // 获取 API
        return [2 /*return*/, {}];
    });
}); };
Try

noEmitOnError

  • 发布版本: 1.4

如果报告了任何错误,则不输出编译器输出文件,如 JavaScript 源代码、源映射或声明文件。

默认值为 false,这使得在类似监视的环境中更容易使用 TypeScript,在这种环境中,你可能希望在确保所有错误都已解决之前,先在其他环境中看到代码更改的结果。

outDir

如果指定,.js(以及 .d.ts.js.map 等)文件将输出到此目录。 原始源文件的目录结构会被保留;如果计算出的根不是你想要的,请参见 rootDir

如果未指定,.js 文件将输出在与生成它们的 .ts 文件相同的目录中:

sh
$ tsc

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

使用如下 tsconfig.json

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

使用这些设置运行 tsc 会将文件移动到指定的 dist 文件夹中:

sh
$ tsc

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

outFile

如果指定,所有全局(非模块)文件将被连接成指定的单个输出文件。

如果 modulesystemamd,则所有模块文件也将在所有全局内容之后连接到该文件中。

注意:除非 moduleNoneSystemAMD,否则不能使用 outFile。此选项不能用于捆绑 CommonJS 或 ES6 模块。

preserveConstEnums

  • 默认值: 如果 isolatedModulestrue,则为 true;否则为 false

  • 发布版本: 1.4

不删除生成的代码中的 const enum 声明。const enum 通过输出枚举值而不是引用,提供了一种在运行时减少应用程序整体内存占用的方法。

例如,使用此 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

默认的 const enum 行为是将任何 Album.Something 转换为相应的数字字面量,并从 JavaScript 中完全删除对枚举的引用。

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

preserveConstEnums 设置为 true 时,enum 在运行时存在,并且数字仍然会输出。

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

这实际上使此类 const enum 仅成为源代码特性,没有运行时痕迹。

removeComments

  • 发布版本: 1.0

在转换为 JavaScript 时,从 TypeScript 文件中去除所有注释。默认为 false

例如,这是一个带有 JSDoc 注释的 TypeScript 文件:

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

removeComments 设置为 true 时:

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

不设置 removeComments 或将其设为 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

这意味着你的注释将显示在 JavaScript 代码中。

sourceMap

  • 发布版本: 1.0

启用源映射文件的生成。 这些文件允许调试器和其他工具在实际处理输出的 JavaScript 文件时显示原始的 TypeScript 源代码。 源映射文件作为 .js.map(或 .jsx.map)文件输出,与相应的 .js 输出文件并列。

.js 文件将依次包含一个源映射注释,以向外部工具指示文件的位置,例如:

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

使用 sourceMap 设置为 true 进行编译会创建以下 JavaScript 文件:

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

并且还会生成此 JSON 映射:

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

sourceRoot

  • 发布版本: 1.0

指定调试器应定位 TypeScript 文件的位置,而不是相对源位置。 此字符串在源映射中会被原样使用,你可以使用路径或 URL:

json
{
  "compilerOptions": {
    "sourceMap": true,
    "sourceRoot": "https://my-website.com/debug/source/"
  }
}

将声明 index.js 的源文件位于 https://my-website.com/debug/source/index.ts

stripInternal 内部

  • 发布版本: 1.5

不输出在 JSDoc 注释中带有 @internal 注解的代码的声明。 这是一个内部编译器选项;请自行承担使用风险,因为编译器不检查结果是否有效。 如果你正在寻找一个工具来处理 d.ts 文件中额外的可见性级别,请查看 api-extractor

ts
/**
 * 一周中的天数
 * @internal
 */
export const 
daysInAWeek
= 7;
/** 计算某人一周的收入 */ export function
weeklySalary
(
dayRate
: number) {
return
daysInAWeek
*
dayRate
;
}
Try

当标志设置为 false(默认)时:

ts
/**
 * 一周中的天数
 * @internal
 */
export declare const daysInAWeek = 7;
/** 计算某人一周的收入 */
export declare function weeklySalary(dayRate: number): number;
Try

stripInternal 设置为 true 时,输出的 d.ts 将被编辑。

ts
/** 计算某人一周的收入 */
export declare function weeklySalary(dayRate: number): number;
Try

JavaScript 输出仍然相同。