項目63 never型のオプションプロパティを使って、排他的論理和をモデリングする
通常の会話では、「または」は排他的論理和(excusive of)を意味する
2つの入力のうちどちらか一方のみが真である場合に真になる論理絵演算
包含的論理和(inclusive of)を使うのはプログラマーと論理学者だけ
2つの入力のどちらか一方または両方が真である場合に真になる論理演算
hr.icon
TypeScriptでは、「または (or)」は包含的論理和(inclusive of)。A | BはAまたはB、またはその両方を意味する
TypeSceriptで排他的論理和をモデリングする方法
タグ付きユニオンを使う
下記の場合、typeの値が'one'と'two'が一緒になることはないため、排他的論理和として扱われる
項目34 ユニオンを含むインターフェイスよりも、インターフェイスのユニオンを選択する
code:ts
interface ThingOneTag {
type: 'one';
shirtColor: string;
}
interface ThingTwoTag {
type: 'two';
hairColor: string;
}
type Thing = ThingOneTag | ThingTwoTag;
never型のオプションプロパティを使う
never型には代入可能な値が存在しないことを活かして排他的論理和をモデリングする
code:ts
interface OnlyThingOne {
shirtColor: string;
hairColor?: never;
}
interface OnlyThingTwo {
hairColor: string;
shirtColor?: never;
}
type ExclusiveThing = OnlyThingOne | OnlyThingTwo;
const bothThings = {shirtColor: 'red',hairColor: 'blue',};
const thing1: OnlyThingOne = bothThings;
// ~~~~~~ Types of property 'hairColor' are incompatible.
const thing2: OnlyThingTwo = bothThings;
// ~~~~~~ Types of property 'shirtColor' are incompatible.
排他的論理和を表現するためのユーティリティ型を定義することもできる
code:ts
type XOR<T1, T2> =
(T1 & {k in Exclude<keyof T2, keyof T1>?: never}) |
(T2 & {k in Exclude<keyof T1, keyof T2>?: never});
type ExclusiveThing = XOR<ThingOne, ThingTwo>;
const allThings: ExclusiveThing = {
// ~~~~~~~~~ Types of property 'hairColor' are incompatible.
// プロパティ 'hairColor' の型に互換性がありません。
shirtColor: 'red',
hairColor: 'blue',
};
#TypeScript