TypeScript における ES6 との兼ね合いで避けているパーツ

ES6 フレンドリな TypeScript のために

先日書いた JSX と TypeScript の混合 Flux または悪魔合体 の経緯から TypeScript と JSX を併用しているため、コードの記述に大きな差ができないよういくつかのパーツ(主に TypeScript のもの)を避けることにしています。

NGなパーツ

独断と偏見です。

Private/Public modifiers

ジャングル ニ プライベート ナイ!

class Acme {
  private himitsu = '';
  public tellme() {}
}

みたいなのですね。バイオ JS にプライベートなんて必要なかったんや。protected も使えるっぽいけどアンドキュメント?

Modules

ES6 ライクな import/export だけ使うということで内部モジュール禁止です。不便ないですね。

// NG(サンプルから拝借)
module Validation {
  export interface StringValidator {
    isAcceptable(s: string): boolean;
  }
}
// OK
export interface StringValidator {
  isAcceptable(s: string): boolean;
}

もちろん d.ts 系では出番ありますが。

Overloads

こういうのもナシ。オーバーロード欲しかったのですが...

// サンプルから拝借
var suits = ["hearts", "spades", "clubs", "diamonds"];

function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x): any {
  if (typeof x == "object") {
    var pickedCard = Math.floor(Math.random() * x.length);
    return pickedCard;
  }
  else if (typeof x == "number") {
    var pickedSuit = Math.floor(x / 13);
    return { suit: suits[pickedSuit], card: x % 13 };
  }
}

仕方ないけど実装は1つしか持てない辺りが使う気を起こさせてくれないので平気。

Enum

贅沢品。

// サンプルから拝借
enum Color {Red, Green, Blue};
var c: Color = Color.Green;

なくても何とかなりますよね。

Implements

本当は使いたいパーツな気もしますが封印中。

// サンプルから拝借
interface ClockInterface {
  currentTime: Date;
  setTime(d: Date);
}

class Clock implements ClockInterface  {
  currentTime: Date;
  setTime(d: Date) {
    this.currentTime = d;
  }
  constructor(h: number, m: number) { }
}

オブジェクト構造を示すのに interface を使いますが、implements はしません的な。

Babel の NG 勢

  • Decorators (es7 proposal stage1)
  • async/await (es7 proposal stage1)
  • Function bind (es7 proposal stage0)

上記、使いたい気もする stage 1 勢が入ってますが、基本的なシンタックスや実装に影響が大きいので自重中です。Decoratorsのことは狙ってますが...

OK なパーツ

これも独断と偏見で。

Property Initializers

ES7 proposal stage 0 相当ですが無いと不安になるの常用。(個人の感想です)

class MyClass {
  foo = 'bar';
  constructor() {
    console.log(this.foo); // 'bar'
  }
}

これないとプロパティの初期化を constructor の中で頑張ることに・・・。ただし次のようなやつ通るのが不可解です。

class MyClass {
  foo = this.bar();
  bar() {
    return 'bar';
  }
  constructor() {
    console.log(this.foo); // 'bar'
  }
}

Babel や TypeScript などの実装上の固有動作なのか、仕様的にこれで正しいことになりそうな雰囲気なのか詳しいひと教えて欲しいです。:(

static/getter/settter

ふつうにES6の範疇にある勢。static は React だと defaultProps とか propTypes で使います。

でした

異論さまざまと思いますし、これも禁止すべき、あれは禁止すべきでない etc あるかと思われますが、自分の手元は現状こんな方針をドキュメント化しています。