Редактировать
После первоначального ответа машинописный текст стал лучше распознавать союзы, поэтому с машинописным шрифтом 3.3 это работает, как и ожидалось:
if (route.tokens[0] === "day") {
// resolve to Day type
route.tokens[0] === 'day'
} else if (route.tokens[0] === "landing") {
// resolve to Landing type
route.tokens[0] === 'landing'
} else {
// resolve to Month type
route.tokens[0] === 'month'
}
Orignial
Хотя решение по написанию type-guard для каждого члена профсоюза является вполне допустимым, оно создает проблемы, если в объединении много членов, или если позже вы добавите дополнительные члены в объединение.
Вы можете создать специальный тип защиты, который защищает все возможные типы, используя условный тип Extract
:
type Landing = {
tokens: ['landing']
};
type Month = {
tokens: ['month', string]
};
type Day = {
tokens: ['day', string, string]
};
type Route =
| Month
| Day
| Landing;
declare let route: Route;
function isRoute<T extends Route['tokens'][0]>(r: Route, type: T): r is Extract<Route, { tokens: [T, ...any[]] }> {
return route.tokens[0] === type;
}
if (isRoute(route, 'day')) {
// resolve to Day type
route.tokens[0] === 'day'
} else if (isRoute(route, 'landing')) {
// resolve to Landing type
route.tokens[0] === 'landing'
} else {
// resolve to Month type
route.tokens[0] === 'month'
}
Ссылка на игровую площадку