TypeScript 型の柔軟性について
多型シグネチャ
TypeScriptでは、関数の引数や戻り値の型を複数の選択肢から指定できる多型シグネチャをサポートしています。これにより、より柔軟で汎用的な関数を定義することが可能になります。
例
function greet(name: string | number): string {
if (typeof name === 'string') {
return `Hello, ${name}!`;
} else {
return `Hello, ${name.toString()}!`;
}
}
この関数は、引数 name
が string
型または number
型のいずれかの場合を受け入れ、常に string
型を返します。
ユニオン型
ユニオン型は、複数の型のいずれかである値を表す型です。多型シグネチャで使用されるだけでなく、変数や関数のパラメータの型としても使用できます。
let value: string | number | boolean;
value = 'hello';
value = 123;
value = true;
この変数 value
は、string
型、number
型、または boolean
型のいずれかの値を保持できます。
多型シグネチャとユニオン型の組み合わせ
多型シグネチャとユニオン型は、組み合わせて使用することで、より複雑な関数を定義することができます。
function getLength(value: string | number[]): number {
if (typeof value === 'string') {
return value.length;
} else {
return value.length;
}
}
この関数は、引数 value
が string
型または number[]
型の場合を受け入れ、いずれの場合でも number
型を返します。
TypeScriptにおける多型シグネチャとユニオン型、および型の柔軟性
多型シグネチャとユニオン型
多型シグネチャは、関数の引数や戻り値の型を複数の選択肢から指定できる機能です。これにより、より柔軟で汎用的な関数を定義することができます。
// 多型シグネチャ
function greet(name: string | number): string {
if (typeof name === 'string') {
return `Hello, ${name}!`;
} else {
return `Hello, ${name.toString()}!`;
}
}
// ユニオン型
let value: string | number | boolean;
value = 'hello';
value = 123;
value = true;
// 多型シグネチャとユニオン型の組み合わせ
function getLength(value: string | number[]): number {
if (typeof value === 'string') {
return value.length;
} else {
return value.length;
}
}
TypeScript 型の柔軟性
TypeScriptは、JavaScriptの型システムを拡張し、より厳密な型チェックを提供します。しかし、柔軟性も備えており、さまざまな状況に対応することができます。
型推論
TypeScriptは、変数の型を自動的に推論することができます。
let x = 10; // xの型はnumberに推論される
型アサーション
型アサーションを使用すると、変数の型を明示的に指定することができます。
let y = document.getElementById('myDiv');
let div = y as HTMLDivElement; // yをHTMLDivElement型にアサートする
インターフェース
インターフェースを使用して、オブジェクトの構造を定義することができます。
interface Person {
name: string;
age: number;
}
let person: Person = {
name: 'John',
age: 30
};
ジェネリクス
ジェネリクスを使用すると、再利用可能な型定義を作成することができます。
function identity<T>(arg: T): T {
return arg;
}
let output = identity<string>('hello');
多型シグネチャの代替手法
オーバーロード
オーバーロードを使用すると、同じ名前の関数を複数のシグネチャで定義することができます。
function greet(name: string): string;
function greet(name: number): string;
function greet(name: string | number): string {
// ...
}
型ガード
型ガードを使用して、変数の型を判定し、それに応じた処理を行うことができます。
function greet(name: string | number): string {
if (typeof name === 'string') {
return `Hello, ${name}!`;
} else if (typeof name === 'number') {
return `Hello, ${name.toString()}!`;
} else {
throw new Error('Invalid type');
}
}
ユニオン型の代替手法
ディスクリミネーション
ディスクリミネーションを使用すると、ユニオン型をより明確に定義することができます。
interface Person {
type: 'person';
name: string;
}
interface Animal {
type: 'animal';
species: string;
}
type Entity = Person | Animal;
function greetEntity(entity: Entity) {
if (entity.type === 'person') {
console.log(`Hello, ${entity.name}!`);
} else if (entity.type === 'animal') {
console.log(`Hello, ${entity.species}!`);
}
}
型推論の制限
型推論の制限を回避するために、明示的に型を指定することができます。
let x: number = 10;
型アサーションの注意
型アサーションは誤った型を指定するとエラーが発生する可能性があるため、慎重に使用してください。
インターフェースの拡張
インターフェースを拡張して、新しいプロパティを追加することができます。
interface Person {
name: string;
}
interface Employee extends Person {
salary: number;
}
ジェネリクスの制約
ジェネリクスの制約を使用して、型のパラメータを制限することができます。
function identity<T extends string | number>(arg: T): T {
return arg;
}
typescript