Я пытаюсь сузить сложный тип, используя охрану типов. Я бы хотел, чтобы ветвь ложного типа охранника понимала дополнение к суженному типу.
interface Model { side: 'left' | 'right'; }
interface LeftModel { side: 'left'; }
interface RightModel { side: 'right'; }
type Either = LeftModel | RightModel;
function isLeft(value: Either): value is LeftModel { // else is RightModel
return value.side === 'left';
}
Это кажется невозможным, по крайней мере, не так, как я это делаю. Typescript рад заключить, что Either
может быть моделью, но не принимает, что Model
может быть Either
. Это дает ошибку:
declare const model: Model;
isLeft(model) // ts(2345)
Эта проблема принципиально неразрешима?
Если нет, то как заставить фальшивую ветвь сузиться до дополнения?
см. Полный пример на этой Площадке машинописного текста
EDIT
Из этого наивного примера видно, что Model
и Either
эквивалентны, но это, вероятно, не может быть обобщено. Я мог бы добиться некоторого прогресса, объединив охрану двух типов в попытке сообщить системе типов, что Model
действительно является действительным Either
(см. Эту новую Playground ). Это, однако, оставляет меня с нежелательной ветвью (см. Строку 22), поэтому не вполне удовлетворительно.
Есть ли способ сообщить системе типов, что Either
и Model
строго эквивалентны?
Мне не нужно особо использовать ни охранники типов, ни объединяемые типы, это была моя первая попытка решить проблему, но она создала собственные проблемы. Объединение типов будет жизнеспособным только в том случае, если мы сможем гарантировать, что объединение суженного типа и его относительного дополнения действительно эквивалентно суженному типу. Это зависит от системы типов, имеющей понимание дополнения, что может быть не так (пока). См. поиск дополнений в машинописи и справочник по типам утилит
Кто-то предложил использовать fp-ts и / или monocle-ts , чтобы решить эту проблему, но некоторые из этих концепций функционального программирования все еще идут мне в голову. Если кто-то знает, как применять их здесь, хотя это было бы хорошо. Либо звучит так, как будто это может помочь здесь ...