クラスに型をつける

INPUT · スライド

フィールド宣言を省く書き方

01 / 05

同じ名前を3回書いている

ここまで書いてきたクラスを、名前だけ見てみよう。namae3回出てくる。フィールドとして宣言して、constructor の引数で受け取って、this.namae に入れる。

持ちものが1つならまだいい。でも4つ5つになると、宣言が5行・引数が5行・代入が5行だ。中身は何もしていないのに、それだけで15行になってしまう。

class Neko {  private namae: string;  constructor(namae: string) {    this.namae = namae;  }  yobu(): string {    return this.namae;  }}const neko = new Neko("たま");console.log(neko.yobu());

実行結果

たま

02 / 05

引数に `private` を付けるだけ

constructor の引数に private を付けると、同じ名前のフィールドが自動で作られて、代入まで済む。宣言の行も this.namae = namae; の行も、もう書かなくていい。

できるものは上のクラスとまったく同じだよ。this.namaeprivatestring として、メソッドから今までどおり使える。この書き方をコンストラクタの短縮記法と呼ぶ。

class Neko {  constructor(private namae: string) {}  yobu(): string {    return this.namae;  }}const neko = new Neko("たま");console.log(neko.yobu());

実行結果

たま

03 / 05

修飾子を付けない引数はフィールドにならない

ここが肝だよ。フィールドになるのは、修飾子を付けた引数だけ。何も付けない引数は、これまでどおり constructor の中でだけ使えるふつうの引数のままだ。

だから下のように private を書き忘れると、this.namae なんて無い、と止められる。付け忘れたときはこのエラーを思い出そう。

class Neko {  constructor(namae: string) {}  yobu(): string {    return this.namae;  }}

実行結果

型のエラー: プロパティ 'namae' は型 'Neko' に存在しません。

04 / 05

`readonly` も同じように書ける

付けられるのは private だけじゃない。readonly も、2つを重ねた private readonly も書ける。付けた修飾子がそのままフィールドの修飾子になるよ。

引数が2つ以上になったら、1行に1つずつ縦に並べよう。375px の画面でも読めるし、あとで持ちものを足すときも増えるのは1行だけだ。

class Kaiin {  constructor(    readonly bangou: number,    private point: number,  ) {}  miru(): number {    return this.point;  }}const k = new Kaiin(7, 30);console.log(k.bangou);console.log(k.miru());

実行結果

7
30

05 / 05

現場のクラスはほとんどこれ

うれしいのは行が減ることだけじゃない。持ちものの一覧が constructor の引数の一覧とぴったり同じになるので、読む人が上と下を見比べなくて済む。だから現場で見かけるクラスは、ほとんどがこの書き方だよ。

できるものは今までのクラスとまったく同じだ。だからインスタンスをそのまま表示すると、private を付けたフィールドも見えてしまう点も変わらない。

ここから書いてみよう。宣言と代入を消して、引数に1語足すだけだ。

class Kudamono {  constructor(    private namae: string,    private nedan: number,  ) {}}const k = new Kudamono("りんご", 120);console.log(k);

実行結果

{ namae: "りんご", nedan: 120 }