TypeScript 1.5

ES6 模块

TypeScript 1.5 支持 ECMAScript 6 (ES6) 模块。ES6 模块实际上就是具有新语法的 TypeScript 外部模块:ES6 模块是独立加载的源文件,可以导入其他模块并提供多个可供外部访问的导出内容。ES6 模块具有若干新的导出和导入声明。建议将 TypeScript 库和应用程序更新为使用新语法,但这并非强制要求。新的 ES6 模块语法可以与 TypeScript 原有的内部和外部模块结构共存,并且这些结构可以随意混合使用。

导出声明

除了现有的 TypeScript 支持通过 export 修饰声明外,模块成员还可以使用单独的导出声明进行导出,并可选择使用 as 子句为导出指定不同的名称。

ts
interface Stream { ... }
function writeToStream(stream: Stream, data: string) { ... }
export { Stream, writeToStream as write }; // writeToStream exported as write

导入声明也可以选择使用 as 子句为导入指定不同的本地名称。例如

ts
import { read, write, standardOutput as stdout } from "./inout";
var s = read(stdout);
write(stdout, s);

作为单独导入的替代方案,可以使用命名空间导入来导入整个模块

ts
import * as io from "./inout";
var s = io.read(io.standardOutput);
io.write(io.standardOutput, s);

重新导出

使用 from 子句,模块可以将给定模块的导出复制到当前模块中,而无需引入本地名称。

ts
export { read, write, standardOutput as stdout } from "./inout";

export * 可用于重新导出另一个模块的所有导出。这对于创建聚合了其他多个模块导出的模块非常有用。

ts
export function transform(s: string): string { ... }
export * from "./mod1";
export * from "./mod2";

默认导出

默认导出(export default)声明指定了一个表达式,该表达式将成为模块的默认导出

ts
export default class Greeter {
sayHello() {
console.log("Greetings!");
}
}

反过来,它可以使用默认导入进行导入

ts
import Greeter from "./greeter";
var g = new Greeter();
g.sayHello();

裸导入

“裸导入”可用于仅为了副作用而导入模块。

ts
import "./polyfills";

有关模块的更多信息,请参阅 ES6 模块支持规范

声明和赋值中的解构

TypeScript 1.5 增加了对 ES6 解构声明和赋值的支持。

声明

解构声明引入一个或多个命名变量,并使用从对象属性或数组元素中提取的值对其进行初始化。

例如,下面的示例声明了变量 xyz,并分别将它们初始化为 getSomeObject().xgetSomeObject().ygetSomeObject().z

ts
var { x, y, z } = getSomeObject();

解构声明也适用于从数组中提取值

ts
var [x, y, z = 10] = getSomeArray();

同样,解构也可用于函数参数声明

ts
function drawText({ text = "", location: [x, y] = [0, 0], bold = false }) {
// Draw text
}
// Call drawText with an object literal
var item = { text: "someText", location: [1, 2, 3], style: "italics" };
drawText(item);

赋值

解构模式也可以用于常规赋值表达式。例如,交换两个变量可以写成一个解构赋值

ts
var x = 1;
var y = 2;
[x, y] = [y, x];

namespace 关键字

TypeScript 使用 module 关键字来定义“内部模块”和“外部模块”;这对于 TypeScript 新手来说造成了一些困惑。“内部模块”更接近大多数人所说的命名空间;同样,JS 中的“外部模块”现在实际上就是指模块。

注意:之前定义内部模块的语法仍然受支持。

之前:

ts
module Math {
export function add(x, y) { ... }
}

之后:

ts
namespace Math {
export function add(x, y) { ... }
}

letconst 支持

在针对 ES3 和 ES5 时,现在支持 ES6 的 letconst 声明。

Const

ts
const MAX = 100;
++MAX; // Error: The operand of an increment or decrement
// operator cannot be a constant.

块级作用域

ts
if (true) {
let a = 4;
// use a
} else {
let a = "string";
// use a
}
alert(a); // Error: a is not defined in this scope.

for..of 支持

TypeScript 1.5 增加了对 ES6 for..of 循环的支持,既适用于 ES3/ES5 的数组,也在针对 ES6 时提供了对迭代器接口的完全支持。

示例

当针对这些版本时,TypeScript 编译器会将数组的 for..of 转换成符合习惯的 ES3/ES5 JavaScript 代码

ts
for (var v of expr) {
}

将被编译为

js
for (var _i = 0, _a = expr; _i < _a.length; _i++) {
var v = _a[_i];
}

装饰器

TypeScript 装饰器基于 ES7 装饰器提案

装饰器是

  • 一个表达式
  • 它求值为一个函数
  • 该函数接收目标、名称和属性描述符作为参数
  • 并可选择返回一个要安装在目标对象上的属性描述符

有关更多信息,请参阅 装饰器 提案。

示例

装饰器 readonlyenumerable(false) 将在属性 method 安装到类 C 之前应用于该属性。这允许装饰器更改实现,在本例中,增强描述符使其 writable 为 false,enumerable 为 false。

ts
class C {
@readonly
@enumerable(false)
method() { ... }
}
function readonly(target, key, descriptor) {
descriptor.writable = false;
}
function enumerable(value) {
return function (target, key, descriptor) {
descriptor.enumerable = value;
};
}

计算属性

使用动态属性初始化对象可能会有些麻烦。以以下示例为例

ts
type NeighborMap = { [name: string]: Node };
type Node = { name: string; neighbors: NeighborMap };
function makeNode(name: string, initialNeighbor: Node): Node {
var neighbors: NeighborMap = {};
neighbors[initialNeighbor.name] = initialNeighbor;
return { name: name, neighbors: neighbors };
}

在这里,我们需要创建一个变量来保存 neighbor-map,以便我们可以初始化它。在 TypeScript 1.5 中,我们可以让编译器来处理这些繁重的工作

ts
function makeNode(name: string, initialNeighbor: Node): Node {
return {
name: name,
neighbors: {
[initialNeighbor.name]: initialNeighbor,
},
};
}

支持 UMDSystem 模块输出

除了 AMDCommonJS 模块加载器外,TypeScript 现在还支持输出 UMD (通用模块定义) 和 System 模块格式。

用法:

tsc —module umd

tsc —module system

字符串中的 Unicode 码点转义

ES6 引入了转义,允许用户仅使用单个转义符来表示 Unicode 码点。

例如,考虑需要转义包含字符 ’𠮷‘ 的字符串。在 UTF-16/UCS2 中,’𠮷’ 表示为代理对,这意味着它使用一对值分别为 0xD8420xDFB7 的 16 位代码单元进行编码。以前,这意味着你必须将码点转义为 "\uD842\uDFB7"。这样做的一个主要缺点是很难将两个独立的字符与代理对区分开来。

使用 ES6 的码点转义,你可以通过单个转义符在字符串和模板字符串中清晰地表示该字符:"\u{20bb7}"。TypeScript 会在 ES3/ES5 中将其输出为 "\uD842\uDFB7"

ES3/ES5 中的标记模板字符串

在 TypeScript 1.4 中,我们为所有目标添加了模板字符串支持,并为 ES6 添加了标记模板支持。感谢 @ivogabe 所做的巨大工作,我们弥补了 ES3 和 ES5 中标记模板的缺失。

当针对 ES3/ES5 时,以下代码

ts
function oddRawStrings(strs: TemplateStringsArray, n1, n2) {
return strs.raw.filter((raw, index) => index % 2 === 1);
}
oddRawStrings`Hello \n${123} \t ${456}\n world`;

将被编译为

js
function oddRawStrings(strs, n1, n2) {
return strs.raw.filter(function (raw, index) {
return index % 2 === 1;
});
}
(_a = ["Hello \n", " \t ", "\n world"]),
(_a.raw = ["Hello \\n", " \\t ", "\\n world"]),
oddRawStrings(_a, 123, 456);
var _a;

AMD 依赖的可选名称

/// <amd-dependency path="x" /> 会通知编译器有一个非 TS 模块依赖,需要将其注入到生成的模块的 require 调用中;但是,之前在 TS 代码中无法使用此模块。

新的 amd-dependency name 属性允许为 amd-dependency 传递一个可选名称

ts
/// <amd-dependency path="legacy/moduleA" name="moduleA"/>
declare var moduleA: MyType;
moduleA.callStuff();

生成的 JS 代码

js
define(["require", "exports", "legacy/moduleA"], function (
require,
exports,
moduleA
) {
moduleA.callStuff();
});

通过 tsconfig.json 实现项目支持

在目录中添加 tsconfig.json 文件表示该目录是 TypeScript 项目的根目录。tsconfig.json 文件指定了编译项目所需的根文件和编译器选项。项目可以通过以下方式之一进行编译

  • 在调用 tsc 时不带输入文件,在这种情况下,编译器会从当前目录开始并沿着父目录链向上搜索 tsconfig.json 文件。
  • 在调用 tsc 时不带输入文件,并使用 -project(或简写为 -p)命令行选项指定包含 tsconfig.json 文件的目录路径。
示例
{
"": "commonjs",
"": true,
"": true
}
}

更多详情,请参阅 tsconfig.json wiki 页面

--rootDir 命令行选项

outDir 选项会在输出中复制输入目录的层级结构。编译器将所有输入文件的最长公共路径计算为输入文件的根目录;然后利用它在输出中复制其所有子结构。

有时这并不理想,例如输入 FolderA\FolderB\1.tsFolderA\FolderB\2.ts 将导致输出结构镜像 FolderA\FolderB\。现在如果向输入中添加了一个新文件 FolderA\3.ts,输出结构将弹出以镜像 FolderA\

rootDir 指定了要在输出中镜像的输入目录,而不是对其进行计算。

--noEmitHelpers 命令行选项

TypeScript 编译器在需要时会输出一些辅助函数,如 __extends。这些辅助函数会出现在它们被引用的每个文件中。如果你想将所有辅助函数整合到一个地方,或者覆盖默认行为,可以使用 noEmitHelpers 来指示编译器不要输出它们。

--newLine 命令行选项

默认情况下,输出换行符在 Windows 系统上为 \r\n,在 *nix 系统上为 \nnewLine 命令行标志允许覆盖此行为,并指定在生成的输出文件中使用的换行符。

--inlineSourceMapinlineSources 命令行选项

inlineSourceMap 会导致 source map 文件以内联方式写入生成的 .js 文件中,而不是作为独立的 .js.map 文件。 inlineSources 允许将源文件 .ts 文件也以内联方式写入 .js 文件中。

TypeScript 文档是一个开源项目。请提交 Pull Request 来帮助我们改进这些页面 ❤

此页面的贡献者
MHMohamed Hegazy (52)
OTOrta Therox (13)
EIEugene Ilyin (1)
SCSadistic Compiler (1)
JBJack Bates (1)
9+

最后更新:2026 年 3 月 27 日