クラスに型をつける

INPUT · スライド

private と readonly で守る

01 / 05

外から勝手に変えられてしまう

フィールドは、なにも書かないと外から自由に読み書きできる。便利だけれど、変な値を入れられても止まらないんだ。

下の zandaka(残高)は、外から -500 にできてしまう。TypeScript から見れば「number の場所に number を入れた」だけなので、これは通ってしまうよ。

class Chokin {  zandaka: number;  constructor(zandaka: number) {    this.zandaka = zandaka;  }}const c = new Chokin(1000);c.zandaka = -500;console.log(c.zandaka);

実行結果

-500

02 / 05

private を付けると外から触れない

フィールドの名前の前に private と書くと、そのクラスの中からしか読み書きできなくなる。外から触ろうとすると、動かす前に止めてくれるよ。

出るのは「プロパティ 'zandaka' はプライベートで、クラス 'Chokin' 内でのみアクセスできます」。

class Chokin {  private zandaka: number;  constructor(zandaka: number) {    this.zandaka = zandaka;  }}const c = new Chokin(1000);c.zandaka = -500;

実行結果

型のエラー: プロパティ 'zandaka' はプライベートで、クラス 'Chokin' 内でのみアクセスできます。

03 / 05

中からは今までどおり

private が効くのは外からだけ。クラスの中のメソッドからは、これまでと同じように this. で読み書きできる。

だから、外に出したい操作だけをメソッドとして用意する。そうすると「マイナスにはしない」のような決まりを、クラスの中で守れるようになるよ。

class Chokin {  private zandaka: number;  constructor(zandaka: number) {    this.zandaka = zandaka;  }  azukeru(gaku: number): void {    this.zandaka = this.zandaka + gaku;  }  miru(): number {    return this.zandaka;  }}const c = new Chokin(1000);c.azukeru(500);console.log(c.miru());

実行結果

1500

04 / 05

readonly は作るときだけ

readonly を付けたフィールドは、constructor で入れたあと変えられなくなる。会員番号や生年月日のように、あとから動いてほしくないものに付けるよ。

読むのは外からでもできる。禁止されるのは書きかえだけだ。

class Kaiin {  readonly bangou: number;  constructor(bangou: number) {    this.bangou = bangou;  }}const k = new Kaiin(7);k.bangou = 9;

実行結果

型のエラー: 読み取り専用プロパティであるため、'bangou' に代入することはできません。

05 / 05

2つはねらいがちがう

  • privateどこから触れるかを決める(クラスの中だけ)
  • readonlyいつまで変えられるかを決める(作るときだけ)

両方を1つのクラスで使ってもいい。迷ったら「外に見せる必要があるか」「あとから変える必要があるか」を、フィールドごとに1つずつ考えてみよう。ここから書いてみよう。

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

実行結果

7
30