bouzuya.hatenablog.com

ぼうずやのにっき

TypeScript で Generator についてまなんだ

@hiroqn が書いた『実例とともに学ぶECMAScript 2015 〜Generator〜 – NET BIZ DIV. TECH BLOG 』を TypeScript で写経して Generator について学んだ。

関連 Tweet は次のとおり。

結果の Gist は https://gist.github.com/bouzuya/1a6b7c8d8c90dddc7f8e0f47beab7589 にある。

ぼくは generator function (function*) を TypeScript でほとんど使わなかったのだけど、すこし分かってきた。今後は使えるところで使っていきたい。 beater の generator function 対応も検討しているので、必要になるだろう。

せっかくなので改めて MDN で Generator について調べた。

Generator - JavaScript | MDN

Generator は generator function (function*) によって返される object だ。Generator は iterable protocol と iterator protocol の両方を満たすものだ。

TypeScript の ES2015 向けの型定義 (lib.es6.d.ts) に従うなら、次のようになる。

// Iterable.prototype.next() の戻り値
interface IteratorResult<T> {
  done: boolean;
  value?: T;
}

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

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

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

TypeScript での GeneratorIterableIterator<T> だ。generator function (function*) は IterableIterator<T> を返す関数だ。IterableIterator<T>Iterator<T> で、それ自身を返す [Symbol.iterator]() を持つ。なるほど。

Iterable<T>for...of / spread operator (...) / yield* / destructuring assignment に対応している。また String / Array / TypedArray / Map / Set は built-in iterable だ。

一度、写経するとすっきりと分かる。書いてみることは大切だな。