TypeScript 1.5

优质
小牛编辑
142浏览
2023-12-01

ES6 模块

TypeScript 1.5 支持 ECMAScript 6 (ES6) 模块. ES6 模块可以看做之前 TypeScript 的外部模块换上了新的语法: ES6 模块是分开加载的源文件, 这些文件还可能引入其他模块, 并且导出部分供外部可访问. ES6 模块新增了几种导入和导出声明. 我们建议使用 TypeScript 开发的库和应用能够更新到新的语法, 但不做强制要求. 新的 ES6 模块语法和 TypeScript 原来的内部和外部模块结构同时被支持, 如果需要也可以混合使用.

导出声明

作为 TypeScript 已有的 export 前缀支持, 模块成员也可以使用单独导出的声明导出, 如果需要, as 语句可以指定不同的导出名称.

interface Stream { ... }
function writeToStream(stream: Stream, data: string) { ... }
export { Stream, writeToStream as write };  // writeToStream 导出为 write

引入声明也可以使用 as 语句来指定一个不同的导入名称. 比如:

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

作为单独导入的候选项, 命名空间导入可以导入整个模块:

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

重新导出

使用 from 语句一个模块可以复制指定模块的导出项到当前模块, 而无需创建本地名称.

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

export * 可以用来重新导出另一个模块的所有导出项. 在创建一个聚合了其他几个模块导出项的模块时很方便.

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

默认导出项

一个 export default 声明表示一个表达式是这个模块的默认导出项.

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

对应的可以使用默认导入:

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

无导入加载

"无导入加载" 可以被用来加载某些只需要其副作用的模块.

import "./polyfills";

了解更多关于模块的信息, 请参见 ES6 模块支持规范.

声明与赋值的解构

TypeScript 1.5 添加了对 ES6 解构声明与赋值的支持.

解构

解构声明会引入一个或多个命名变量, 并且初始化它们的值为对象的属性或者数组的元素对应的值.

比如说, 下面的例子声明了变量 x, yz, 并且分别将它们的值初始化为 getSomeObject().x, getSomeObject().ygetSomeObject().z:

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

解构声明也可以用于从数组中得到值.

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

相似的, 解构可以用在函数的参数声明中:

function drawText({ text = "", location: [x, y] = [0, 0], bold = false }) {
    // 画出文本
}

// 以一个对象字面量为参数调用 drawText
var item = { text: "someText", location: [1,2,3], style: "italics" };
drawText(item);

赋值

解构也可以被用于普通的赋值表达式. 举例来讲, 交换两个变量的值可以被写作一个解构赋值:

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

namespace (命名空间) 关键字

过去 TypeScript 中 module 关键字既可以定义 "内部模块", 也可以定义 "外部模块"; 这让刚刚接触 TypeScript 的开发者有些困惑. "内部模块" 的概念更接近于大部分人眼中的命名空间; 而 "外部模块" 对于 JS 来讲, 现在也就是模块了.

注意: 之前定义内部模块的语法依然被支持.

之前:

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

之后:

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

letconst 的支持

ES6 的 letconst 声明现在支持编译到 ES3 和 ES5.

Const

const MAX = 100;

++MAX; // 错误: 自增/减运算符不能用于一个常量

块级作用域

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 时对满足 Iterator 接口的全面支持.

例子

TypeScript 编译器会转译 for...of 数组到具有语义的 ES3/ES5 JavaScript (如果被设置为编译到这些版本).

for (var v of expr) { }

会输出为:

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

装饰器

TypeScript 装饰器是局域 ES7 装饰器 提案的.

一个装饰器是:

  • 一个表达式
  • 并且值为一个函数
  • 接受 target, name, 以及属性描述对象作为参数
  • 可选返回一个会被应用到目标对象的属性描述对象

了解更多, 请参见 装饰器 提案.

例子

装饰器 readonlyenumerable(false) 会在属性 method 添加到类 C 上之前被应用. 这使得装饰器可以修改其实现, 具体到这个例子, 设置了 descriptorwritable: false 以及 enumerable: false.

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

计算属性

使用动态的属性初始化一个对象可能会很麻烦. 参考下面的例子:

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, 我们可以让编译器来干重活:

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

指出 UMDSystem 模块输出

作为 AMDCommonJS 模块加载器的补充, TypeScript 现在支持输出为 UMD (Universal Module Definition) 和 System 模块的格式.

用法:

tsc --module umd

以及

tsc --module system

Unicode 字符串码位转义

ES6 中允许用户使用单个转义表示一个 Unicode 码位.

举个例子, 考虑我们需要转义一个包含了字符 '