TypeScript での共用体型と交差型
TypeScript には、型を宣言するためのさらに高度なオプションが用意されています。 共用体型と交差型は、ある型が 2 つ以上の可能な型で構成されている状況を処理するのに役立ちます。 リテラル型を使用すると、型に代入される値を、少数のオプションのリストに制約できます。
共用体型
共用体型は、複数の型のいずれかにできる値を記述するのに使用します。 この柔軟性は、値を自分で制御できない場合 (たとえば、ライブラリ、API、ユーザー入力からの値など) に役立ちます。
any
型でも異なる型を受け取ることができるのに、共用体型を使用する必要があるのはなぜでしょう? 共用体型を使用すると、値の代入を共用体で指定した型に制限できるのに対し、any
型では制限できません。 もう 1 つの理由は、Intellisense のサポートです。
共用体型では、縦棒つまりパイプ (|
) を使用して、各型を区切ります。 次の例では、multiType
には number
または boolean
を使用できます。
let multiType: number | boolean;
multiType = 20; //* Valid
multiType = true; //* Valid
multiType = "twenty"; //* Invalid
型ガードを使用すると、共用体型の変数を簡単に操作できます。 この例の add
関数が受け取る 2 つの値には、number
または string
を使用できます。 両方の値が number 型の場合は、それらが加算されます。 両方とも string 型の場合は、連結されます。 それ以外の場合はエラーが返されます。
function add(x: number | string, y: number | string) {
if (typeof x === 'number' && typeof y === 'number') {
return x + y;
}
if (typeof x === 'string' && typeof y === 'string') {
return x.concat(y);
}
throw new Error('Parameters must be numbers or strings');
}
console.log(add('one', 'two')); //* Returns "onetwo"
console.log(add(1, 2)); //* Returns 3
console.log(add('one', 2)); //* Returns error
交差型
交差型は共用体型と密接に関係していますが、使用方法は異なります。 交差型を使用すると、2 つ以上の型が結合されて、既存の型のすべてのプロパティを持つ新しい型が作成されます。 交差により、既存の型を組み合わせて、必要なすべての機能を備えた 1 つの型を取得できます。
交差型で各型を区切るには、アンパサンド (&
) を使用します。
交差型を最もよく使用するのはインターフェイスです。 次の例では、Employee
と Manager
という 2 つのインターフェイスを定義した後、両方のインターフェイスのプロパティを併せ持つ ManagementEmployee
という新しい交差型を作成します。
interface Employee {
employeeID: number;
age: number;
}
interface Manager {
stockPlan: boolean;
}
type ManagementEmployee = Employee & Manager;
let newManager: ManagementEmployee = {
employeeID: 12345,
age: 34,
stockPlan: true
};
インターフェイスの詳細については、「TypeScript でのインターフェイスの実装」モジュールで学習できます。
リテラル型
リテラルは、集合型のより具体的なサブタイプです。 つまり、"Hello World"
は string
ですが、型システム内では string
は "Hello World"
ではありません。
TypeScript で使用できるリテラル型のセットは、string
、number
、boolean
の 3 つです。 リテラル型を使用すると、string、number、またはブール値が持つ必要のある値を正確に指定できます (たとえば、"yes"、"no"、"maybe" など)。
リテラルの縮小とは
TypeScript で var
または let
を使用して変数を宣言すると、この変数の内容が変更される場合があることがコンパイラに通知されます。 let を使用して変数を宣言すると、その変数の型が指定され (たとえば string
)、無制限の数の有効な値を持つことができます。
これに対し、const
を使用して変数を宣言すると、このオブジェクトが決して変更されないことが TypeScript に通知されます。 const
を使用して宣言すると、それは値に型指定されます (たとえば "Hello World")。
無限の数の潜在的ケースを、もっと小さい有限の数の潜在的ケースにするプロセスは、縮小と呼ばれます。
リテラル型の定義
リテラル型は、オブジェクト、配列、関数、またはコンストラクター型のリテラルとして記述され、他の型から新しい型を作成するために使用されます。
リテラル型の使用方法を示すのに最もよいのは、例を使用することです。 この型定義により testResult
というリテラル型が作成され、それには 3 つの string
値のいずれかを格納できます。
type testResult = "pass" | "fail" | "incomplete";
let myResult: testResult;
myResult = "incomplete"; //* Valid
myResult = "pass"; //* Valid
myResult = "failure"; //* Invalid
変数 myResult
の値を設定するとき、"incomplete"
と "pass"
は有効なエントリですが、"failure"
は testResult
型の定義の項目の 1 つではないため、有効ではありません。
TypeScript には数値のリテラル型もあり、文字列リテラルと同じように動作します。 次に例を示します。
type dice = 1 | 2 | 3 | 4 | 5 | 6;
let diceRoll: dice;
diceRoll = 1; //* Valid
diceRoll = 2; //* Valid
diceRoll = 7; //* Invalid
また、リテラル型または型の任意の組み合わせを定義するときは、boolean
値を使用することもできます。