Поток жалуется на несовместимость типов, хотя я сначала проверяю тип - PullRequest
1 голос
/ 05 февраля 2020

Я написал выпадающий компонент React, который я могу предоставить любому из следующих элементов:

  • Массив string s
  • Массив простого JSON объекта каждое из которых содержит два свойства text и icon.

Мои простые типы потоков выглядят следующим образом:

type DropdownMenuItemType = DropdownMenuIconAndTextType | string;

type DropdownMenuIconAndTextType ={
    text: string,
    icon?: React$Element<React$ElementType>;
}

Предыдущие версии компонента поддерживают только строки. Добавление элемента для поддержки text и icon является новым запросом функции, который я нахожусь в процессе реализации. Я не хочу каких-либо серьезных изменений для моих существующих пользователей.

Поэтому в моем компоненте я пытаюсь преобразовать любой string, предоставленный и обернуть его в DropdownMenuIconAndTextType, чтобы все получилось в этом виде. Элементы, которые уже DropdownMenuIconAndTextType, просто остаются такими.

let Array<DropdownMenuItemType> originalItems = 
let Array<DropdownMenuIconAndTextType> convertedItems = [];
{'English', 'French', 'German', {text: 'Dutch', icon : <SomeIcon />}};
     items.forEach( (currItem: DropdownMenuItemType) => {
           if(typeof currItem === DropdownMenuIconAndTextType){
               convertedItems.push(currItem);
           }
           else {
               convertedItems.push({text: currItem.toString()});
           }

}); 

Однако в потоке есть одна ошибка с:

  if(typeof currItem === DropdownMenuIconAndTextType){
               convertedItems.push(currItem);
  }

, и он говорит, что currItem все еще может быть string и несовместимо с convertedItems, несмотря на то, что тип проверяется как DropdownMenuIconAndTextType.

Что мне нужно сделать, чтобы удовлетворить поток в этом сценарии? Заранее спасибо.

1 Ответ

2 голосов
/ 05 февраля 2020

Я полагаю, что вы смешиваете различие между кодом типа Flow и кодом JS.

Внутри сигнатур типа typeof возвращает тип литерального значения, как описано здесь . В коде JS, который существует во время выполнения, например, в вашем операторе if, typeof просто скажет вам, является ли что-то строкой, объектом и т. Д. c., Как описано здесь, Таким образом, левая часть вашего условного оператора будет иметь значение "string" или "object", а не фактический тип потока переменной.

Справа от вашего условного выражения имеется тип потока. DropdownMenuIconAndTextType, который существует только во время проверки типа, но не во время выполнения. Я немного удивлен, что из-за этого Flow не выдает ошибку.

Попробуйте что-то вроде этого:

  if(typeof currItem !== 'string'){
               convertedItems.push(currItem);
  }

Это проверит, существует ли значение, которое существует во время выполнения строка или объект, который должен работать с уточнениями типа Flow.

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