Не возвращать generi c type, если не определено - PullRequest
2 голосов
/ 08 мая 2020

Не знаю, возможно ли реализовать это с помощью TS.

Здесь - игровая площадка, было бы лучше понять.


У меня есть значение по умолчанию группы типов

type DefaultTypes = 'group1' | 'group2'

И интерфейсная группа

interface Group<N> {
  type: DefaultTypes | N
  label: string
}

И функция для registerGroups

function registerGroups <T>(group: Group<T>) {}

Таким образом я могу добавить больше групп типов в DefaultTypes, но если я вызываю registerGroups({}) без типа generi c, TS не возвращает ошибку другому типу группы.

Есть ли способ заставить его работать?

Thx

1 Ответ

3 голосов
/ 08 мая 2020

Typescript определяет параметры типа из аргументов, которые вы передали. В этом случае, если вы не укажете параметр типа, компилятор выведет его на основе значения, которое вы присваиваете type, поэтому для этого примера:

registerGroups({
  label: 'Group 4',
  type: 'group4' // How make TS return an error here?
})

T выводится как group4. Это спроектированное поведение, и оно должно работать. Наилучший вид функции generi c - это такой, который не требует от вас явно передавать параметры типа.

Нет встроенного способа отключить вывод, есть некоторые обходные пути, основанные на идее, что мы можем запутать компилятор, чтобы отказаться от вывода на определенном сайте аргументов, используя некоторые условные типы. Это решение от jcalz - это то, что я обычно использую в таких случаях. Соедините это со значением по умолчанию для T из never, и вы получите ожидаемое поведение. Значение по умолчанию необходимо, потому что, если TS не имеет места для вывода T, по умолчанию используется unknown, а unknown | N - unknown, поэтому можно назначить что угодно. Но если T по умолчанию never, мы получим never | N, что упрощается до N, поэтому будут присваиваться только значения типа N:

type NoInfer<T> = [T][T extends any ? 0 : never];
function registerGroups <T = never>(group: Group<NoInfer<T>>) {}

// group4 is not in Types, but no error
registerGroups({
  label: 'Group 4',
  type: 'group4' // How make TS return an error here?
})

Playground Link

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...