Не могу пропустить реквизиты условного типа, который никогда не должен возвращаться из-за логического вывода - как? - PullRequest
1 голос
/ 21 апреля 2019

Я пытаюсь воспользоваться реакцией ввода типов для реализации (для изучения цели) структуры представления.Все хорошо и прекрасно, за исключением того, что при попытке смешать conditional type с типом Omit (для демонстрации этого необходим пакет @types/react):

import {DetailedHTMLFactory, ReactHTML} from 'react'

type Tags = keyof ReactHTML

type ReactPropsFrom<Tag extends Tags> =
  ReactHTML[Tag] extends DetailedHTMLFactory<infer P, any> ? P : never

На данный момент у меня есть свойства дляHTMLElement в соответствии с определениями реакции с использованием (для якорей) ReactPropsFrom<'a'>.Что осталось сделать, так это удалить специфические свойства реакции.Давайте определим некоторые из них:

type ReactSpecificProps =         |
  'defaultChecked'                |
  'defaultValue'                  |
  'suppressHydrationWarning'      |
  'suppressContentEditableWarning'

И тип Omit

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>

Если я сделаю Omit<ReactPropsFrom<'a'>, ReactSpecificProps>, то все в порядке, и у меня есть в результирующем типе все свойства Iхочу.

Но если я сделаю более общий подход, например, так:

type Props<Tag extends Tags> = Omit<ReactPropsFrom<Tag>, ReactSpecificProps>

Я получаю эту ошибку

// type ReactSpecificProps = "defaultChecked" |...
// Type '"defaultChecked"' is not assignable to type 'keyof ReactPropsFrom<Tag>'.
// Type '"defaultChecked"' is not assignable to type 'never'

Я понимаю это как ReactPropsFrom может вернуть never (даже если это никогда не произойдет, так как переданный универсальный элемент всегда расширяется Tags), и в этом случае средство проверки типа прерывается.Но так как я понимаю, почему я не могу найти способ избежать этой проблемы.

Наивно я прыгал что-то вроде:

type Props<Tag extends Tags> = Omit<ReactPropsFrom<Tag>!, ReactSpecificProps>

с оператором bang ! (насколько я знаюникогда не будет never), но его нельзя использовать для определения типа (?).Любая подсказка?

Заранее спасибо Seb

1 Ответ

1 голос
/ 21 апреля 2019

Вы можете пройти через много трудностей, чтобы убедить компилятор, что ReactPropsFrom<Tag> действительно содержит ReactSpecificProps, но я бы посоветовал против этого.Тип Omit, который входит в 3.5, не ограничивает K быть keyof T ( PR и отклонением для добавления ограничения ).Таким образом, решение состоит в том, чтобы просто удалить ограничение на K, и все это будет работать.

Для полноты, это то, что убедило бы компилятор (по крайней мере, то, что я придумал, могут быть более короткие пути).):

type Props<Tag extends Tags> = ReactPropsFrom<Tag> extends infer U ?
    [U] extends [Partial<Record<ReactSpecificProps, any>>] ? Omit<U, ReactSpecificProps> : never: never;
...