Обобщения TypeScript: определение пересечения типов с объединением - PullRequest
0 голосов
/ 18 апреля 2020

Я создаю библиотеку TypeScript, которая использует некоторые интерфейсы из другой библиотеки. Я пытаюсь определить тип из пересечения обобщенного типа c и интерфейса, которым я не управляю, в сочетании с объединением между void, которое имеет особое значение в библиотеке зависимостей.

Я попытался создать минимальное представление проблемы, с которой я сталкиваюсь.

export type AllProps<Props> = (Props & IDependecyProps) | void;

interface MyProps {
  disableCache: boolean;
}

function doTheThing(props: AllProps<MyProps>) {
  // Property 'disableCache' does not exist on type 'AllProps'.
  //  Property 'disableCache' does not exist on type 'void'.ts(2339)
  console.log(props.disableCache);
}

Моя цель состоит в том, чтобы AllProps позволил вам указать либо disableCache, либо любые свойства в IDependecyProps, ИЛИ тип приводит к void. Библиотека, от которой я зависим, имеет особое значение для типа void, что делает ее полезной.

РЕДАКТИРОВАТЬ: я сделал пример кода слишком простым, забыл добавить обобщенный тип c.

Ответы [ 2 ]

0 голосов
/ 19 апреля 2020

Простой if уточнит тип и исключит void:

function doTheThing(props: AllProps) {
  if (props) {
    console.log(props.disableCache); // props is narrowed to MyProps & IDependecyProps
  }
}

Управляющий анализ потока сужает тип от props внутри if до MyProps & IDependecyProps.

Кроме того, if необходим в любом случае для предотвращения ошибки во время выполнения (props параметр может быть undefined в соответствии с определением его типа).

Детская площадка

0 голосов
/ 18 апреля 2020

Вы можете использовать утверждение типа в своих реквизитах и ​​проверить наличие свойства, поскольку ваш пример boolean, нам нужно проверить, не является ли он undefined

Подробнее Здесь


interface IDependecyProps {
    something: number
}
export type AllProps = (MyProps & IDependecyProps) | void;

interface MyProps {
  disableCache: boolean;
}

function doTheThing(props: AllProps) {

  if ( typeof((props as MyProps).disableCache)!=='undefined' )
  console.log((props as MyProps).disableCache);
}
doTheThing({ disableCache: false, something:1})

Детская площадка

...