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

TypeScript 1.5

ES6 模块

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

导出声明

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

ts
interface Stream { ... }
function writeToStream(stream: Stream, data: string) { ... }
export { Stream, writeToStream as write };  // writeToStream 作为 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";

默认导出

默认导出声明指定一个表达式,该表达式成为模块的默认导出:

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 }) {
  // 绘制文本
}

// 使用对象字面量调用 drawText
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; // 错误:递增或递减运算符的操作数不能是常量。

块级作用域

ts
if (true) {
  let a = 4;
  // 使用 a
} else {
  let a = "string";
  // 使用 a
}

alert(a); // 错误:在此作用域中未定义 a。

for..of 支持

TypeScript 1.5 增加了对数组的 ES6 for..of 循环在 ES3/ES5 中的支持,以及在目标为 ES6 时对迭代器接口的全面支持。

示例

当目标为 ES3/ES5 时,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 };
}

这里我们需要创建一个变量来保存邻居映射以便初始化。 使用 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 中,'𠮷' 表示为一个代理对,这意味着它使用一对 16 位码元值进行编码,具体为 0xD8420xDFB7。 以前这意味着你必须将码点转义为 "\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 依赖传递一个可选名称:

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 文件的目录的路径。

示例
json
{
  "compilerOptions": {
    "module": "commonjs",
    "noImplicitAny": true,
    "sourceMap": 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 使源映射文件内联在生成的 .js 文件中,而不是放在独立的 .js.map 文件中。 inlineSources 允许额外将源 .ts 文件内联到 .js 文件中。