yaakaito.org

TypescriptのジェネリクスをObject Type Literalと組み合わせると結構強力

TypeScript

こんにちは!うきょーです! TypeScriptのジェネリクスとObject Type Literalを組み合わせると結構強力なのでその紹介。

Object Type Literalとはなんぞや

例えばこういうオブジェクトに対して、

1
2
3
4
var v = {
    a: 'a',
    b: 123
}

こういう型注釈を与えられるのがObject Type Literalです。

1
2
3
4
var v: {a: string, b: number} = {
    a: 'a',
    b: 123
}

TypeScriptのinterfaceはこのObject Type Literalに別名を与えられるもので、本質的には同じです。 大抵の場合は型推論されたり、interfaceを使うので、あんまり書く事はありません。(その方が見やすいしね)

なんですが、本質的に同じものなので、これをinterfaceのようにジェネリクスの引数型にextendsさせたりすることができます。

ジェネリクスと組み合わせると

こんな感じにかけます、{}がちょっとダサいですね。

1
2
3
4
5
6
7
8
9
class Fuga<T extends { piyopiyo(): string }> {

  constructor(private object: T) { }

  callPiyoPiyo() {
    this.object.piyopiyo();
  }

}

これでpiyopiypを実装しているものだけ受け付けるようになります。便利ですね。

使う側でも書けて

こういうこともできますが、こっちはまず使わないですね、はい。

1
new Fuga<{piyopiyo(): string, foofoo(): string}>();

あんまりやすぎるとしんどいので

実装してほしいメソッドが1つあるけど、その為にinterface書くのだるいし〜、くらいの時につかうとよいと思います。