ホームページ > ウェブフロントエンド > jsチュートリアル > TypeScript ジェネリック: 完全ガイド

TypeScript ジェネリック: 完全ガイド

Susan Sarandon
リリース: 2025-01-04 04:15:42
オリジナル
188 人が閲覧しました

TL;DR: TypeScript ジェネリックを使用すると、開発者は型の安全性を維持しながらさまざまなデータ型を処理できる再利用可能なコードを作成できます。これらは、堅牢でスケーラブルな TypeScript アプリを構築するために不可欠です。

TypeScript Generics: A Complete Guideコードの透明性と管理性を確保するために、Typescript では数種類のデータを安全かつ効果的に管理する必要があります。 Typescript の中核機能の 1 つは Typescript ジェネリックスです。これにより、厳格な型制限を遵守しながら関数、クラス、インターフェイスを作成できます。ジェネリックを使用すると、作成するコードの量が減り、間違いが少なくなり、そして最も重要なことに、さまざまなデータ型に対応した柔軟なコンポーネントを構築できます。

この記事では、関数、クラス、インターフェイスでの使用法など、タイプスクリプト ジェネリックスの本質を探り、コードをどのように多用途かつ堅牢にするかを示します。

Typescript ジェネリックとは何ですか?

Typescript ジェネリックは、プレースホルダー型を使用して Typescript コードを定義できるため、タイプセーフを維持しながら、柔軟性、拡張性、再利用可能にすることができます。

Typescript は、ジェネリック型を定義するプレースホルダーとしてコンパイル時に型の安全性チェックを行います。コンポーネントが実装されると、プレースホルダーは実際の型に置き換えられます。この手法を使用すると、データ型ごとに個別の実装を必要としないため、重複性の管理と削減が容易になります。

ジェネリックを使用しないと、異なるデータ型を処理するために複数のバージョンの関数またはクラスを作成することになり、コードの重複が発生します。ジェネリックを使用すると、静的な型チェックを維持しながら、さまざまな種類に再利用可能な単一の実装が可能になります。

次のセクションのコード例は、この違いを理解するのに役立ちます。

Typescript ジェネリックをいつ使用するか?

ジェネリックを typescript のさまざまな部分で使用すると、型をより効率的に管理できます。これらは、柔軟性が重要な関数、インターフェイス、クラス、その他の構造に役立ちます。

1. 関数内のジェネリック型

ジェネリックは、冗長性を減らすために関数に適用されることがよくあります。たとえば、文字列または数値をパラメータとして受け取る関数について考えてみましょう。

function identity(value: any): any {
  return value;
}
const result1 = identity(42); // result1: any
const result2 = identity("hello"); // result2: any
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

この機能は正常に動作します。ただし、任意の型を使用するため、Typescript は特定の型を追跡できなくなります。その結果、戻り値の型は any, となり、Typescript はタイプ セーフを強制できなくなります。型の安全性を維持する必要がある場合は、2 つの異なる関数を作成する必要があります。1 つは文字列を返し、もう 1 つは数値を返します。ただし、このアプローチではコードの重複が増加します。

ジェネリックを使用して型情報を保存することで、上記の関数を改善できます。

function identity(value: any): any {
  return value;
}
const result1 = identity(42); // result1: any
const result2 = identity("hello"); // result2: any
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

T は、この場合メソッドが使用する型を表します。存在する場合、Typescript は入力の型と戻りパラメーターの型が同じであることを確認します。

また、パラメータの型を明示的に定義せずに関数を定義することもできます。

function identity<T>(value: Type): T {
  return value;
}
const result1 = identity<number>(42); // result1: number
const result2 = identity<string>("hello"); // result2: string
ログイン後にコピー
ログイン後にコピー

Typescript では、単一の関数またはコンポーネントで複数の型を操作するときに、複数のジェネリック型パラメーターを使用できます。たとえば、2 つの異なるタイプの入力を受け取り、それらをペアとして返す関数が必要になる場合があります。

const result3 = identity(100); // result3: number
const result4 = identity("world"); // result4: string
ログイン後にコピー

この場合、関数は型 T の最初の要素と型 U の 2 番目の要素を持つタプルを返します。これにより、関数による 2 つの異なる型の型安全な処理が可能になります。

2. typescript のデフォルトの型

Typescript では、ジェネリックにデフォルトの型を提供して、それをオプションにすることができます。タイプが指定されていない場合、Typescript はデフォルトを使用します。

function multipleParams<T, U>(first: T, second: U): [T, U] {
 return [first, second];
}
const result1 = multipleParams<string, number>("hello", 42); // result1: [string, number]
const result2 = multipleParams<string, number>("hello", "world"); // result2: gives a type error
ログイン後にコピー

この例では、型パラメータ T のデフォルトは文字列です。開発者が関数を呼び出すときに特定の型を指定しない場合、T はデフォルトで文字列になります。

3. 汎用インターフェース

Typescript ジェネリックスはインターフェイスにも適用できます。 任意の タイプの値を持つ Box インターフェースを定義するとします。

function createArray<T = string>(length: number, value: T): T[] {
 return Array(length).fill(value);
}

const stringArray = createArray(3, "hello"); // T defaults to string, so stringArray is a string array
const numberArray = createArray<number>(3, 42); // T is explicitly set to a number, so numberArray is a number array
ログイン後にコピー

これは一般的な関数の例とより同等です。特定の型を定義していないため、このコードも問題なく動作します。ただし、値は any, として型付けされるため、型関連のバグが発生する可能性があります。

型を保護するために、ここで汎用インターフェイスを定義できます。

interface Box {
  value: any;
}
const numberBox: Box = { value: 123 }; // correct
const stringBox: Box = { value: "hello" }; // correct
ログイン後にコピー

インターフェイスは汎用であり、その値の型は Type 変数に厳密に制限されます。 Type 変数は、インスタンスの作成時に数値または文字列として指定できるため、Typescript は適切な型が遵守されるようになります。

4. 汎用クラス

クラスは、型の安全性を維持しながらさまざまな型を処理するジェネリックスを使用して作成することもできます。 任意の型の値を格納および取得できるStorageクラスを作成しましょう。

interface Box<Type> {
  value: Type;
}
const numberBox: Box<number> = { value: 123 }; // number
const stringBox: Box<string> = { value: "hello" }; // string
const stringBox2: Box<string> = { value: 123 }; // incorrect
ログイン後にコピー

このクラスは機能しますが、データの型が any, であるため、getItem メソッドは any, を返し、タイプ セーフティが削除されます。したがって、ジェネリックスを使用してクラスを書き直して、型安全性を向上させることができます。

class Storage {
  private data: any;
  setItem(item: any): void {
    this.data = item;
  }
  getItem(): any {
    return this.data;
  }
}
const storage = new Storage();
storage.setItem(123);
const item = storage.getItem();
ログイン後にコピー

この場合、タイプ TStorage クラスによって使用されます。 Typescript は、インスタンスの作成時にデータの型を定義するときに、データが正しいことを保証します。このコード例の getItem メソッドは数値を生成します。

5. 一般的な制約

ジェネリック制約を使用すると、ジェネリックが受け入れることができる型を制限し、ジェネリックが特定のプロパティを持つようにすることができます。

たとえば、入力の length プロパティにアクセスする必要がある関数がある場合、制約を使用して、length プロパティを持つ型のみが許可されるようにすることができます。 。これにより、Typescript でエラーが発生したり、互換性のない型がすり抜けたりすることがなくなります。

function identity(value: any): any {
  return value;
}
const result1 = identity(42); // result1: any
const result2 = identity("hello"); // result2: any
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

ここでは、値 Tlength プロパティで定義されていません。この問題を無視するには、Tlength プロパティが必要であることを指定する制約を追加します。これを行うには、T extends { length:number }.
とします。

function identity<T>(value: Type): T {
  return value;
}
const result1 = identity<number>(42); // result1: number
const result2 = identity<string>("hello"); // result2: string
ログイン後にコピー
ログイン後にコピー

この関数には length プロパティが含まれます。エラーは発生せず、入力の長さで実行されます。

結論

Typescript ジェネリックを使用すると、柔軟性があり、再利用可能で、タイプセーフなコードを作成できます。これらのジェネリックを持つクラス、メソッド、インターフェイスを使用すると、コードを繰り返さずに多くのデータ型を管理できます。汎用制約、多数の型、およびデフォルトの型は、この投稿で取り上げた主要な使用例の一部であり、それぞれがプログラムのスケーラビリティと保守性をどのように向上させることができるかを示しました。

Typescript ジェネリックスを理解すると、より正確で、適応性があり、タイプセーフなコードを作成し、Typescript アプリケーションをより堅牢にすることができます。

関連ブログ

  • Webpack と Vite: どのバンドラーが最適ですか?
  • シングルスパを使用したマイクロ フロントエンドの構築: ガイド
  • RxJS で非同期 JavaScript をマスターする
  • Axios と Fetch API?適切な HTTP クライアントの選択

以上がTypeScript ジェネリック: 完全ガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート