Comments 3
type State =
| { isFetching: true }
| { isFetching: false; task: Task }
| { isFetching: false; error: Error }
Небольшое предостережение. Несмотря на то, что эта возможность очень мощная, используйте её аккуратно. Т.к. кол-во проивзодимых типов растёт в геометрической прогрессии. Я очень быстро это понял когда попытался скрестить типы для props у одного хитрого react-компонента с базовыми props для html-элементов. TypeScript завис, отъел около 4 GiB и тут же умер. Перезапуск, разумеется не помог. Пришлось поумерить аппетиты. Оно видимо там внутри вычисляется не ленивым образом. Мне повезло и оно упало сразу, т.к. пример явно вырожденный. Но я мог наткнуться на это в более приземлённых примерах и просто шаг за шагом убивать DX в ноль и даже не догадываться в чём дело.
Ещё 1 момент про эту возможность. Так можно определять разные сигнатуры для callback-ов в зависимости от какого-нибудь другого аргумента. Но… Доказать typescript-у очевидные вещи уже внутри метода не получится, т.к. сужение типа далеко не всемогущее. Т.е. по сути подобные финты приводят к "невозможным типам" с &
. Но as whatever
конечно выручает.
type Task = {}
type State =
| { isFetching: true }
| { isFetching: false; task: Task }
| { isFetching: false; error: Error }
function foo(state: State) {
if ('error' in state) {
// Тип сузился до { isFetching: false; error: Error }
} else if ('task' in state) {
// Тип { isFetching: false; task: Task }
} else {
// Тип { isFetching: true }
}
}
Было бы интересно взглянуть на ваш пример из-за которого завис компилятор TypeScript.
Типы внутри метода будут нормально работать если написать type guard
Только для простых случаев. Вот как вы напишете type-guard на метод? У вас в наличии только мутный .length
, который лучше вообще не трогать :) По сути далеко не все вещи можно за type-guard-ить. Так что внутри будут скорее всего не guard-ы, а приведение типов согласно бизнес логике.
Было бы интересно взглянуть на ваш пример из-за которого завис компилятор TypeScript
Я подписал бумагу согласно которой я не могу показывать такие вещи :) Но если кратко, то там:
- есть property
tag
которая может быть либо React.ComponentType либо строка - если строка — то цепляем все доступные HTMLElement-ам property тоже (а их там больше 100)
- если ComponentType то цепляем
React.ComponentProps<typeof tag>
(их обычно не больше 5-7 - помимо этого есть ещё 2 более простых вилки такого вида:
{ a?: undefined, b: boolean } | { a: boolean, b?: undefined }
. Т.е. что-то одно точно задано, и никогда не заданы оба - это всё, как не трудно догадаться, ещё и с генериком для
tag
чтобы можно было выцепить его props
Продвинутый TypeScript