はじめに
この記事は【Generics(ジェネリクス)】についての備忘録である
【Generics(ジェネリクス)】とは
- 抽象的な型引数を使用して、実際に利用されるまで型が確定しない
クラス
・関数
・インターフェイス
を実現する。 - ジェネリクスは、型も引数のように扱うという発想。
- ジェネリクスは、コードの共通化と型の安全性を両立するための言語機能。
// <T> が型変数名の定義である
function changeBackgroundColor<T>(element: T) {
// any に型アサーションすればコンパイルエラーは回避できる
// 型チェックされないのでバグの可能性
(element as any).style.backgroundColor = "red";
return element;
}
【Generics(ジェネリクス)】に制約をつける
TypeScript
では extends
キーワードを用いることでジェネリクスの型Tを特定の型に限定することができる
以下の例ではとすることで型 T
は必ず HTMLElement
またはそのサブタイプの HTMLButtonElement
や HTMLDivElement
であることが保証されるため 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;
};
コメント