edy hub

プログラミングやライフスタイルについて書き綴っています

プロを目指す人のためのTypeScript入門を読んでみて〜第五章〜

はじめに

業務で使うことのあるTypeScriptを本格的に勉強し始めたところです。

現在絶賛『プロを目指す人のためのTypeScript入門』を読み進めており、その際のメモを備忘録として残しております。

第五章は「TypeScriptのクラス」を扱っています。

書籍はこちら

型引数を持つクラス

クラスも型引数を持てます。

これまで登場したのは「型そのもの」や「関数」が型引数を持つケース。

「クラスの型引数」は両方を合体させたような性質を持つと。

イメージを付けるためにコードを参照します。

class User<T> {
  name: string;
  #age: number;
  readonly data: T;

  constructor(name: string, age: number, data: T) {
    this.name = name;
    this.#age = age;
    this.data = data;
  }

  public isAdult(): boolean {
    return this.#age >= 20;
  }
}

const taro = new User<string>("taro", 21, "日本人です")
const data = taro.data;
const john = new User("John Smith", 15, { num: 123 })
const data2 = john.data;

特徴としてはクラス宣言でUserと型引数リストが書かれています。クラス名の後のTには方が入ります。 結果、UserやUserなどのインスタンスが生成可能になります。

コンストラクタの呼び出し時に型引数を指定できます。

例: new クラス<型引数リスト>(引数リスト)

これでインスタンスの data に対して型の指定ができるようになりました。

ちなみにdata2の方では型の指定がありません。この場合、型推論{ num: number; } 型であることが推論されます。

最終的にjohnがどんな型のインスタンスになるかというと

User<{ num: number; }> 型であるといえます。

クラスの継承

TypeScriptでも継承が出てきましたね。

  • 他言語と同様あるクラスに機能を追加・拡張した別クラスを作成する「継承」の機能を持つ
  • キーワードは extends
  • class クラス名 extends 親クラス { ... } で継承を表現する

先程と同様にソースコードで具体イメージを掴んでみましょう。

class User {
  name: string;
  #age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.#age = age;
  }

  public isAdult(): boolean {
    return this.#age >= 20;
  }
}

class PremiumUser extends User {
  rank: number = 1;
}

const taro = new PremiumUser("taro", 21)
console.log(taro.rank); // 1が表示される
console.log(taro.name); // "taro"が表示される
console.log(taro.isAdult()); // trueが表示される

User クラスを継承した PremiumUser クラスが宣言されています。 つまり PremiumUser クラスも User クラスの全機能を備えます。 加えて rank プロパティを持つため taro.rank を呼び出せました。

また多言語と同様に子クラスでは親機能を上書きする「オーバーライド」も可能です。

例外処理

5章ではTypeScriptでの例外処理にも言及されていました。

エラーの基本としてはエラーを発生させる「throw文」が登場します。

throw 式; の構文があり、式部分でErrorオブジェクトを指定します。 例えば以下のような例外発生方法があります。

console.log('エラー発生させます')
throwError();
console.log('エラーを発生させました')

function throwError() {
  const error = new Error("エラーが発生しました!")
  throw error;

}

この場合「エラーを発生させました」は実行されずエラーのthrow時点で処理は中断されます。 エラーを補足しながら処理を継続する場合は try-catch 文を用います。

try {
  // エラーが発生しうる処理
} catch {
  // エラー発生時に発火する処理
}

エラーが発生してもしなくても実行する処理を書きたいときは finally ブロックを用います。

まとめ

第5章ではクラスに触れました

  • クラスに型を適用できる
  • クラスの継承が可能
  • thisや例外処理も含めたTypeScriptの追加機能の紹介