ジェネリック型以外の方法
TypeScriptにおける <T> の意味
ジェネリック型の例
例えば、identity
という名前の関数を考えてみましょう。この関数は、与えられた値をそのまま返す単純な関数です。
function identity(value: number): number {
return value;
}
この関数は数値を受け取り、数値を返します。しかし、この関数は数値以外にも適用できます。例えば、文字列やオブジェクトを受け取っても、そのまま返すことができます。
const str = identity("Hello"); // str は "Hello" 型
const obj = identity({ name: "John" }); // obj は { name: "John" } 型
この問題を解決するために、ジェネリック型を使用できます。
function identity<T>(value: T): T {
return value;
}
このコードでは、<T>
というジェネリック型パラメータが追加されています。これは、identity
関数が どんな型でも受け取り、その型そのままを返す ことを意味します。
上記の例では、identity
関数は以下のように使用できます。
const num = identity(10); // num は number 型
const str = identity("Hello"); // str は string 型
const obj = identity({ name: "John" }); // obj は { name: "John" } 型
ジェネリック型を使用することで、以下のような利点があります。
- コードの再利用性: ジェネリック型を使用することで、コードをさまざまなデータ型に適用できるため、コードを再利用することができます。
- コードの簡潔性: ジェネリック型を使用することで、コードをより簡潔に書くことができます。
- 型の安全性: ジェネリック型を使用することで、型の安全性が高まります。
ジェネリック型は、TypeScript で非常に強力な機能です。詳細については、以下のリソースを参照してください。
ジェネリック型を使った関数
function identity<T>(value: T): T {
return value;
}
const num = identity(10); // num は number 型
const str = identity("Hello"); // str は string 型
const obj = identity({ name: "John" }); // obj は { name: "John" } 型
ジェネリック型を使ったインターフェース
interface Person<T> {
name: string;
age: number;
data: T;
}
const person1: Person<string> = {
name: "John",
age: 30,
data: "This is a string."
};
const person2: Person<number> = {
name: "Jane",
age: 25,
data: 12345
};
ジェネリック型を使ったクラス
class GenericClass<T> {
private data: T;
constructor(data: T) {
this.data = data;
}
getData(): T {
return this.data;
}
}
const myClass1 = new GenericClass<string>("Hello");
const myClass2 = new GenericClass<number>(10);
ジェネリック型以外の方法
型パラメータ
ジェネリック型を使用する代わりに、型パラメータ を使用することができます。型パラメータは、関数の引数として型を渡すことができます。
function identity(value: any): any {
return value;
}
const num = identity(10); // num は number 型
const str = identity("Hello"); // str は string 型
const obj = identity({ name: "John" }); // obj は { name: "John" } 型
この例では、identity
関数は any
型の型パラメータを受け取ります。これにより、identity
関数はどんな型でも受け取り、その型そのままを返すことができます。
型ガード
型ガード を使用して、コードを特定の型に絞り込むことができます。
function identity(value: number | string): number | string {
if (typeof value === "number") {
return value + 1;
} else {
return value.toUpperCase();
}
}
const num = identity(10); // num は number 型
const str = identity("Hello"); // str は string 型
この例では、identity
関数は number
型または string
型の引数を受け取ります。typeof
演算子を使用して、引数の型をチェックし、それに応じて処理を分岐します。
discriminated union
discriminated union を使用して、異なる型を持つ値を区別することができます。
interface Person {
type: "person";
name: string;
age: number;
}
interface Animal {
type: "animal";
species: string;
age: number;
}
function identity(value: Person | Animal): Person | Animal {
if (value.type === "person") {
return value.name.toUpperCase();
} else {
return value.species.toUpperCase();
}
}
const person: Person = {
type: "person",
name: "John",
age: 30,
};
const animal: Animal = {
type: "animal",
species: "Dog",
age: 5,
};
const personName = identity(person); // personName は string 型
const animalSpecies = identity(animal); // animalSpecies は string 型
この例では、Person
インターフェースと Animal
インターフェースは、type
プロパティによって区別されます。identity
関数は、Person
型または Animal
型の引数を受け取り、type
プロパティに基づいて処理を分岐します。
これらの方法は、ジェネリック型と同様に、コードを汎用的に再利用するために使用できます。どの方法を使用するかは、状況によって異なります。
ジェネリック型は、TypeScript で非常に強力な機能です。コードを汎用的に再利用し、コードを簡潔に書くことができます。
typescript