Template String Types as Discriminants
TL;DR
ユニオン型の判別にテンプレートリテラルが使えるようになった。
おさらい
ユニオン型(Union Type)
|
を使った型のOR条件。
type A = {};
type B = {};
type MyUnion = A | B; // <=== AまたはB
function doSomething(
value: number | string // <=== numberまたはstring
) { ... }
テンプレートリテラル(Template Literal Types)
`${}`
を使った文字列テンプレート。
type Lang = "en" | "ja" | "pt";
type Locale = `i18n-${Lang}`; // <=== これ
const locale: Locale = "i18n-ja";
本題
例として、システムエラーの種類をユニオン型で宣言する。
// 致命的エラー: XXXCriticalError
type CriticalError = {
id: `${string}CriticalError`;
redirectUrl: URL;
};
// 一時的なエラー: XXXTempolaryError
type TemporaryError = {
id: `${string}TempolaryError`;
displayMessage: string;
};
// ユニオン型で束ねておく
type SystemError = CriticalError | TemporaryError;
ユニオン型の「どの型にマッチするのか」をテンプレート文字列で指定できるようになった。
function errorHandler(error: SystemError) {
if (error.id === "DBConnectionCriticalError") {
location.href = error.redirectUrl.href;
}
if (error.id === "MaintenanceTempolaryError") {
window.alert(error.displayMessage);
}
...
}
ifの条件分岐だけでなくswitchでも使える。
function errorHandler(error: SystemError) {
switch(error.id) {
case "DBConnectionCriticalError":
location.href = error.redirectUrl.href;
return;
case "MaintenanceTempolaryError":
window.alert(error.displayMessage);
return;
...
}
}
間違ったプロパティの参照はコンパイルエラーで気付くことができる。
// CriticalErrorはdisplayMessageを持っていない
if (error.id === "DBConnectionCriticalError") {
error.displayMessage; // Error: Property does not exist on type
}
Last updated