Pull to refresh

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 guard или использовать оператор in:

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
Sign up to leave a comment.