TypeScript 的 ES6 类型

Map<K, V>

let map2 = new Map(); // Key any, value any
let map3 = new Map<string, number>(); // Key string, value number

TypeScript 使用 Map 类型,描述 Map 结构。

const myMap: Map<boolean,string> = new Map([
  [false, 'no'],
  [true, 'yes'],
]);

Map 是一个泛型,使用时,比如给出类型变量。

由于存在类型推断,也可以省略类型参数。

const myMap = new Map([
  [false, 'no'],
  [true, 'yes'],
]);

Set<T>

本站补充(原稿此节仅有标题):Set<T> 描述元素类型为 T 的集合。集合使用 add 添加值,用 has 判断值是否存在,重复添加相同值不会增加成员数量。类型参数约束传入方法的值,但不会在运行时执行额外的类型验证。

const names = new Set<string>();
names.add('Ada');
names.add('Ada');
names.size; // 1
names.has('Ada'); // true

集合的对象值按引用身份区分;两个内容相同但独立创建的对象仍是两个元素。相应运行环境需要支持 Set,只改变 TypeScript 的 lib 选项并不会安装运行时实现。

Promise<T>

本站补充(原稿此节仅有标题):Promise<T> 的类型参数描述成功兑现后的值;它不描述拒绝原因的类型,也不会把同步值自动变成异步操作。

const result: Promise<number> = Promise.resolve(42);
result.then(value => value.toFixed(0));

async function answer(): Promise<number> {
  return 42;
}

then 回调里的 value 推断为 number。await 取得成功结果;拒绝需要通过 try/catch 或 catch 处理。类型检查和 Promise 的运行行为是两层机制,相关运行语义参见 Promise 对象。

async 函数

async 函数的的返回值是一个 Promise 对象。

const p:Promise<number> = /* ... */;

async function fn(): Promise<number> {
  var i = await p;
  return i + 1;
}

Iterable<T>

对象只要部署了 Iterator 接口,就可以用for...of循环遍历。Generator 函数(生成器)返回的就是一个具有 Iterator 接口的对象。

TypeScript 使用泛型Iterable<T>表示具有 Iterator 接口的对象,其中T表示 Iterator 接口包含的值类型(每一轮遍历获得的值)。

interface Iterable<T> {
  [Symbol.iterator](): Iterator<T>;
}

上面是Iterable<T>接口的定义,表示一个具有Symbol.iterator属性的对象,该属性是一个函数,调用后返回的是一个 Iterator 对象。

Iterator 对象必须具有next()方法,另外还具有两个可选方法return()和throw(),类型表述如下。

interface Iterator<T> {
  next(value?: any): IteratorResult<T>;
  return?(value?: any): IteratorResult<T>;
  throw?(e?: any): IteratorResult<T>;
}

上面的类型定义中,可以看到next()、return()、throw()这三个方法的返回值是一个部署了IteratorResult<T>接口的对象。

IteratorResult<T>接口的定义如下。

interface IteratorResult<T> {
  done: boolean; //表示遍历是否结束
  value: T; // 当前遍历得到的值
}

上面的类型定义表示,Iterator 对象的next()等方法的返回值,具有done和value两个属性。

下面的例子是 Generator 函数返回一个具有 Iterator 接口的对象。

function* g():Iterable<string> {
  for (var i = 0; i < 100; i++) {
    yield '';
  }
  yield* otherStringGenerator();
}

上面示例中,生成器g()返回的类型是Iterable<string>,其中string表示 Iterator 接口包含的是字符串。

这个例子的类型声明可以省略,因为 TypeScript 可以自己推断出来 Iterator 接口的类型。

function* g() {
  for (var i = 0; i < 100; i++) {
    yield ""; // infer string
  }
  yield* otherStringGenerator();
}

另外,扩展运算符(...)后面的值必须具有 Iterator 接口,下面是一个例子。

function toArray<X>(xs: Iterable<X>):X[] {
  return [...xs]
}

Generator 函数

Generator 函数返回一个同时具有 Iterable 接口(具有[Symbol.iterator]属性)和 Iterator 接口(具有next()方法)的对象,因此 TypeScript 提供了一个泛型IterableIterator<T>,表示同时满足Iterable<T>和Iterator<T>两个接口。

interface IterableIterator<T> extends Iterator<T> {
    [Symbol.iterator](): IterableIterator<T>;
}

上面类型定义中,IterableIterator<T>接口就是在Iterator<T>接口的基础上,加上[Symbol.iterator]属性。

下面是一个例子。

function* createNumbers(): IterableIterator<number> {
  let n = 0;
  while (1) {
    yield n++;
  }
}

let numbers = createNumbers()

// {value: 0, done: false}
numbers.next()

// {value: 1, done: false}
numbers.next()

// {value: 2, done: false}
numbers.next()

上面示例中,createNumbers()返回的对象numbers即具有next()方法,也具有[Symbol.iterator]属性,所以满足IterableIterator<T>接口。

参考链接