TypeScriptのUnion型と関数をマスターすれば、もっと自由度の高いコードが書ける
TypeScriptにおけるUnion型と関数
Union型の基本
Union型は、パイプ記号 |
を使って複数の型を列挙することで定義します。 例えば、以下は、文字列型または数値型のUnion型です。
type StringOrNumber = string | number;
この型は、StringOrNumber
変数に文字列リテラルまたは数値リテラルを代入することを許可します。
let myStringOrNumber: StringOrNumber = "Hello";
myStringOrNumber = 10;
関数におけるUnion型
関数の引数や戻り値の型にUnion型を使用することができます。 例えば、以下は、文字列型または数値型を引数とし、文字列型を返す関数です。
function addOrConcat(x: string | number, y: string | number): string {
if (typeof x === 'string' && typeof y === 'string') {
return x + y;
} else {
return x + y;
}
}
この関数は、string
型と number
型の両方を受け入れ、それらを文字列として連結または加算して返します。
let result = addOrConcat("Hello", 10); // result は "Hello10" になります
result = addOrConcat(10, 20); // result は 30 になります
function getRandomValue(): string | number {
if (Math.random() < 0.5) {
return Math.random().toString();
} else {
return Math.random() * 100;
}
}
この関数は、ランダムな文字列または数値を返します。
let value: string | number = getRandomValue();
if (typeof value === 'string') {
console.log(`文字列: ${value}`);
} else {
console.log(`数値: ${value}`);
}
型絞り込み
Union型は、条件分岐を使って絞り込むことができます。 例えば、以下のコードでは、addOrConcat
関数の引数に基づいて、結果の型を絞り込んでいます。
function addOrConcat(x: string | number, y: string | number): string | number {
if (typeof x === 'string') {
return (x + y) as string; // result は string 型になります
} else {
return x + y; // result は number 型になります
}
}
このコードでは、x
が文字列型のときのみ、結果の型を string
型に絞り込んでいます。
Union型は、様々な場面で使用することができます。 例えば、以下のような用途があります。
- コードをより汎用的にする場合
- 異なる種類のデータを扱う場合
- APIからの応答を処理する場合
文字列型または数値型のUnion型を持つ関数
この例では、文字列型または数値型の引数を受け取り、それらを連結または加算して返す関数を作成します。
function addOrConcat(x: string | number, y: string | number): string | number {
if (typeof x === 'string' && typeof y === 'string') {
return x + y;
} else {
return x + y;
}
}
この関数は、以下のように使用できます。
let result = addOrConcat("Hello", 10); // result は "Hello10" になります
result = addOrConcat(10, 20); // result は 30 になります
文字列型または数値型のいずれかを返す関数
function getRandomValue(): string | number {
if (Math.random() < 0.5) {
return Math.random().toString();
} else {
return Math.random() * 100;
}
}
let value: string | number = getRandomValue();
if (typeof value === 'string') {
console.log(`文字列: ${value}`);
} else {
console.log(`数値: ${value}`);
}
この例では、APIからのJSON応答を処理する関数を作成します。 応答には、ユーザー名と年齢を含むオブジェクトが含まれています。
interface UserResponse {
name: string;
age: number;
}
function processUserResponse(response: string | UserResponse): void {
if (typeof response === 'string') {
console.error(`エラー: ${response}`);
} else {
console.log(`ユーザー名: ${response.name}`);
console.log(`年齢: ${response.age}`);
}
}
let response1: string | UserResponse = '{ "name": "John Doe", "age": 30 }';
let response2: string | UserResponse = '予期せぬエラーが発生しました。';
processUserResponse(response1); // ユーザー名: John Doe、年齢: 30 と出力されます
processUserResponse(response2); // エラー: 予期せぬエラーが発生しました。 と出力されます
この例では、正方形と円の面積を計算する関数を作成します。
interface Square {
type: 'square';
sideLength: number;
}
interface Circle {
type: 'circle';
radius: number;
}
function calculateArea(shape: Square | Circle): number {
if (shape.type === 'square') {
return shape.sideLength * shape.sideLength;
} else {
return Math.PI * shape.radius * shape.radius;
}
}
let square: Square = { type: 'square', sideLength: 5 };
let circle: Circle = { type: 'circle', radius: 10 };
let squareArea = calculateArea(square); // squareArea は 25 になります
let circleArea = calculateArea(circle); // circleArea は 314.1592653589793 になります
型ガード
型ガードを使用して、Union型の値の型を特定することができます。 例えば、以下のコードでは、addOrConcat
関数の引数が文字列型かどうかを確認しています。
function addOrConcat(x: string | number, y: string | number): string | number {
if (typeof x === 'string') {
return (x + y) as string; // result は string 型になります
} else {
return x + y; // result は number 型になります
}
}
このコードでは、typeof x === 'string'
という条件式を使用して、x
が文字列型かどうかを判断しています。 この条件式が真の場合、x + y
の型を string
型に明示的にキャストしています。 これにより、コンパイラは result
変数が文字列型であることを認識することができます。
ジェネリック型
ジェネリック型を使用して、Union型を含む関数をより汎用的にすることができます。 例えば、以下のコードでは、2つの値を受け取り、それらを連結または加算するジェネリック関数を作成します。
function addOrConcatGeneric<T>(x: T, y: T): T {
if (typeof x === 'string' && typeof y === 'string') {
return x + y;
} else {
return x + y;
}
}
この関数は、T
というジェネリック型パラメータを持っています。 これにより、この関数は、引数と戻り値が任意の型であることができます。 例えば、以下のように使用できます。
let result1 = addOrConcatGeneric<string>('Hello', 'World'); // result1 は "HelloWorld" になります
let result2 = addOrConcatGeneric<number>(10, 20); // result2 は 30 になります
型推論
TypeScriptの型推論機能を使用して、Union型の型を明示的に指定する必要がない場合があります。 例えば、以下のコードでは、addOrConcat
関数を使用していますが、引数と戻り値の型を明示的に指定していません。
let result = addOrConcat("Hello", 10);
typescript