🎃

【イラスト付き】型の利用【丁寧に解説】

2024/09/04に公開

はじめに

皆さんこんにちは。
今回はTypeScriptの型の利用方法をご紹介します。

TypeScriptは型を利用する際に型アノテーションという書き方を使います。また処理を汎用的に扱うためのジェネリクスという仕組みを持っています。今回はTypeScriptの型の利用方法についてご紹介します。

こんな人にオススメ

  • TypeScriptの型アノテーションの書き方を知りたい
  • TypeScriptのジェネリクスの書き方を知りたい

初めて学習する方にも分かるように、丁寧に解説していきます。
すでに利用されている方も、是非一度目を通していただけると嬉しいです。

😋 TypeScriptの型の利用方法をご紹介します♪

型アノテーション

まずポイントをチェック

  • 変数の型指定
    • : (コロン)の右側に型を指定
  • 関数の型指定
    • 戻り値なしはvoid型を指定
    • 処理が終了しない場合は戻り値にnever型を指定

型アノテーションとは、コード内で型を指定する記述です。

変数の型指定

変数の型を指定するには変数名の右側に「:」を置いて型名を指定します。

TypeScript/04.use-type/app.ts(変数宣言のみ抜粋)
// 変数宣言
const moji: string = 'abc';

関数の型指定

関数では引数と戻り値型を指定します。引数は変数宣言と同じように、右側に「:」を置いて型名を指定します。戻り値の型は引数リストの右側に「:」を置いて型名を指定します。

戻り値の型はreturn文から推論することもできます。推論を利用することで冗長的にならずスッキリと記述することができます。戻り値の型を明示するために記述しても問題ありません。

戻り値なしの場合はvoidを指定し、無限ループのような終了しない処理はneverを指定します。

TypeScript/04.use-type/app.ts(関数宣言のみ抜粋)
// 関数宣言(戻り値あり)
const fn1 = (x: number, y: number): string => 'abc';

// 関数宣言(戻り値なし)
const fn2 = (x: number): void => { console.log(x); };

// 関数宣言(終了しない)
const fn3 = (): never => { while (true) { } };

😋 「:」で変数や引数に型を指定します♪

ジェネリクス

まずポイントをチェック

  • 特定の型に依存せず、汎用的なコードになる
    • 型が違うだけのコードを何個も作らないで済む
  • 型を仮置きする
    • extendsで仮置きの型を特定の型に限定

ジェネリクスとは関数や配列などで扱う値の型を仮置きする仕組みです。特定の型に依存しない汎用的なコードにすることができます。

もし特定の型に依存した関数などを作ってしまうと、同じ処理を行いたい場合に似たような関数を型の種類に応じて作らなければいけません。その処理の用途や再利用性を踏まえてジェネリクスを導入しましょう。

ジェネリクスは「<T>」で型を仮置きします。このTはTypeの頭文字から取られています。

下記の関数の例は、引数xと戻り値の型を利用時に決定するようTで仮置きしています。利用時は<string>のように具体的な型を指定します。実行時にTの部分はstringに置き換わります。よって実行時はstring型の引数になり、戻り値型もstring型の関数として動作します。

TypeScript/04.use-type/app.ts(ジェネリクスのみ抜粋)
// ジェネリクス
const fn4 = <T>(x: T): T => { return x };
fn4<string>('abc'); // Tをstring型に指定して利用

extendsで利用可能な型を限定

仮置きのT型にはどんな型でも適用できます。利用可能な型を制限するにはextendsを使います。「<T extends 型名」のように記述することで、extendsで指定した型を満たす型のみ利用可能になります。

これによってTはextendsで指定された型の特徴を満たすことが保証されます。基本データ型をextendsで指定した場合は、その型であることが保証されます。

下記の例はTが数値であることを保証する例です。

TypeScript/04.use-type/app.ts(extendsで基本データ型を指定のみ抜粋)
// extendsで絞り込み
// xはnumberである
const fn5 = <T extends number>(x: T): T => { return x };
fn5<number>(100);

ユニオン型をextendsで指定した場合は、ユニオン型が持ついずれかの型であることが保証されます。

下記の例はTが’A’型、’B’型、’C’型のいずれかであることを保証する例です。

TypeScript/04.use-type/app.ts(extendsでユニオン型を指定のみ抜粋)
// xはA、B、Cのどれかである
type arphabet = 'A' | 'B' | 'C';
const fn7 = <T extends arphabet>(x: T): T => { return x };

オブジェクト型をextendsで指定した場合は、その型が特定のプロパティを持つことが保証されます。これにより入力補完や型チェックでコーディングしやすくなります。

下記の例はTがtitleとpriceのプロパティを持つあることを保証する例です。

TypeScript/04.use-type/app.ts(extendsでオブジェクト型を指定のみ抜粋)
// bookはBook型である(titleとpriceを持つと保証)
interface Book { title: string, price: number };
const fn6 = <T extends Book>(book: T): string => { return book.title };

😋 型を仮置きして汎用性を高くします♪

おわりに

皆さん、お疲れ様でした。
ここまでご覧いただき、ありがとうございました。

型の利用方法について確認をしていただきました。
TypeScriptでは型アノテーションを使って利用する型を宣言します。
またジェネリクスを使うことで型を仮置きして汎用的に扱えるようになります。

😋 これからもプログラミング学習頑張りましょう♪

参考リンク集
参考リンク集(サンプルコード)

Discussion