【TypeScript】【Generics(ジェネリクス)】について

はじめに

この記事は【Generics(ジェネリクス)】についての備忘録である

【Generics(ジェネリクス)】とは

  • 抽象的な型引数を使用して、実際に利用されるまで型が確定しないクラス関数インターフェイスを実現する。
  • ジェネリクスは、型も引数のように扱うという発想。
  • ジェネリクスは、コードの共通化と型の安全性を両立するための言語機能。
// <T> が型変数名の定義である
function changeBackgroundColor<T>(element: T) {
  // any に型アサーションすればコンパイルエラーは回避できる
  // 型チェックされないのでバグの可能性
  (element as any).style.backgroundColor = "red";
  return element;
}

【Generics(ジェネリクス)】に制約をつける

TypeScript では extends キーワードを用いることでジェネリクスの型Tを特定の型に限定することができる
以下の例ではとすることで型 T は必ず HTMLElement またはそのサブタイプの HTMLButtonElementHTMLDivElement であることが保証されるため style プロパティに安全にアクセスできるようになる

function changeBackgroundColor<T extends HTMLElement>(element: T) {
  element.style.backgroundColor = "red";
  return element;
}

【Generics(ジェネリクス)】にデフォルト型引数を設定する

関数の引数にデフォルト値を指定するように、ジェネリクスでもデフォルトの型引数を指定することができる。

・// エラーイベントを表すMyErrorEventという型を定義
type MyErrorEvent<T> = {
  error: T;
  type: string;
};

例外処理を記述する時にNetworkErrorのように対応するエラークラスをすべて用意することはなく、標準のErrorで対応してしまうケースも多くありますが、今の状態ではMyErrorEventのジェネリクスの型Tを常に指定する必要があり非常に面倒である。

// 型 T が必須なので、MyErrorEvent<Error>と指定する必要がある。
// Generic type 'MyErrorEvent' requires 1 type argument(s).
const errorEvent: MyErrorEvent = {
  error: new Error("エラーです"),
  type: "syntax",
};

そこで、<T = Error>とすることでデフォルト型引数としてErrorを指定することで、ジェネリクスの型Tは必要な時だけ指定して、何も指定してない場合は自動でErrorとすることができる。

type MyErrorEvent<T = Error> = {
  error: T;
  type: string;
};

コメント

タイトルとURLをコピーしました