TypeScript: как сказать TypeScript, в каком случае я? - PullRequest
0 голосов
/ 23 октября 2018

Я создаю приложение React Native, используя TypeScript.Мой стартап недавно переключился на TypeScript из JavaScript, и я переносил код.

У меня есть <FlatList />, который состоит из двух типов заведений: Ресторан и Бар.Ресторан и бар разделяют некоторые свойства, но они также не имеют.Например, свойство servesFood является уникальным для ресторанов.

Функция renderItem выглядит следующим образом:

renderItem = ({ item }: { item: Restaurant | Bar }) => {
  return item.servesFood ? (
    // ... Restaurant code
  ) : (
    // ... Bar code
  )

Проблема в том, что в условии для этого троичного оператора выдает TypeScriptошибка:

Property 'servesFood' does not exist on type 'Restaurant | Bar'.
  Property 'servesFood' does not exist on type 'Bar'

Кроме того, в коде, специфичном для типа, при доступе к свойствам, специфичным для типа, также есть ошибки linting.

Примечание: По разным причинам я не могупусть они совместно используют свойство и устанавливают для него значение true на first, а на false - на другое.

Так как я могу сказать TypeScript, что в одной части оператора предложения / троичного оператора Ifэлемент относится к типу Restaurant, а другой элемент относится к типу bar, так что эти ошибки при обработке исчезают.

Ответы [ 2 ]

0 голосов
/ 23 октября 2018

Вы можете просто сравнить ключ / значение объекта, чтобы узнать, существует ли свойство serveFood для текущего элемента.Если значение равно null, это означает, что item не содержит свойства servesFood Примерно так:

renderItem = ({ item }: { item: Restaurant | Bar }) => {
  return ((item["servesFood"] != null) ? (
    // ... Restaurant code, it exists the property servesFood
  ) : (
    // ... Bar code, it doesn't exists the property servesFood so it is null
  ))
0 голосов
/ 23 октября 2018

Вы можете использовать охрану типа, чтобы сузить тип параметра.

Вы можете использовать различимые союзы на основе поля servesFood:

interface Restaurant{
    servesFood: true
}
interface Bar {
  servesFood?: false
}
const renderItem = ({ item }: { item: Restaurant | Bar }) => {
      return item.servesFood ? (
        // ... Restaurant code
      ) : (
        // ... Bar code
      )

Или, если интерфейсы не разделяют servesFood, вы можете использовать in type guard

interface Restaurant{
    servesFood: true
}
interface Bar {
  drinks: true
}
const renderItem = ({ item }: { item: Restaurant | Bar }) => {
      return 'servesFood' in item ? (
        item.servesFood
      ) : (
        // ... Bar code
        item.drinks
      );
...