TypeScript 1.7 が公開されて async await--target es6 オプションだけでコンパイルできるようになりました。

しかし実行できる環境は今のところないようです。しかたがないので Babel を組み合わせて使ってみます。

TypeScript で asyncfunction* を使った適当なコードを用意しました。

// src/a.ts

import { count, delay } from './b';

async function main(): Promise<void> {
    for (const x of count()) {
        if (x === 2 ** 2) break;
        console.log(x);
        await delay(1000);
    }
}

main();
// src/b.js

export function delay(ms: number) {
    return new Promise((resolve) => void setTimeout(resolve, ms));
}

export function* count() {
    let i: number = 0;
    for (;;)
        yield i++;
}

--target es6 オプションを指定すれば tsc でコンパイルはできるのが確認できます。

変換する

TypeScript と Babel の両方の変換を組み合わせるために Gulp を使います。

Babel の preset は es2015 に加えて async/await のために stage-3 もインストールします。ジェネレータ構文のために polyfill も使います。

$ npm install -g gulp
$ npm install -D babel-preset-es2015 babel-preset-stage-3 gulp-babel gulp-typescript
$ npm install -S babel-polyfill

gulpfile.js を用意します。 Node.js 4 から arrow function が使えるので積極的に使っていきます。

// gulpfile.js

const gulp = require('gulp');
const babel = require('gulp-babel');
const typescript = require('gulp-typescript');

gulp.task('default', () => gulp
    .src(['src/**/*.ts'])
    .pipe(typescript({ target: 'es6' }))
    .pipe(babel({ presets: ['stage-3', 'es2015'] }))
    .pipe(gulp.dest('lib')));

実行すると lib の中に JavaScript が出来上がります。実行するときは babel-polyfill を一緒に読み込みます。

$ gulp
$ node -r babel-polyfill lib/a.js

3秒かけて0から3まで表示します。

SourceMaps

開発中は SourceMaps がほしいので対応させます。

$ npm install -D gulp-sourcemaps source-map-support
// gulpfile.js

const gulp = require('gulp');
const babel = require('gulp-babel');
const sourcemaps = require('gulp-sourcemaps');
const typescript = require('gulp-typescript');

gulp.task('default', () => gulp
    .src(['src/**/*.ts'])
    .pipe(sourcemaps.init())
    .pipe(typescript({ target: 'es6' }))
    .pipe(babel({ presets: ['stage-3', 'es2015'] }))
    .pipe(sourcemaps.write({ sourceRoot: 'src' }))
    .pipe(gulp.dest('lib')));

gulp を実行すると SourceMaps 付きで JavaScript が作られます。実行するときは source-map-support/registerrequire します。

$ node -r babel-polyfill -r source-map-support/register lib/a.js

さらに Browserify を組み合わせたりもできます。 Browserify の場合一旦保存する必要があるので Gulp を使ううまみが減る気がしますが。