【问题标题】:TypeScript: How to tell TypeScript in which If case I am?TypeScript:如何告诉 TypeScript 我是哪种情况?
【发布时间】:2019-03-27 18:56:48
【问题描述】:

我正在使用 TypeScript 构建一个 React Native 应用程序。我的创业公司最近从 JavaScript 切换到 TypeScript,我正在迁移代码。

我有一个<FlatList />,它包含两种类型的场所:餐厅和酒吧。 Restaurant 和 Bar 共享一些属性,但它们也不共享。例如属性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 错误。

注意:出于各种原因,我不能让他们共享一个属性并将first 的一个设置为true,另一个设置为false。

那么我如何告诉 TypeScript 在 If 子句/三元运算符项的一部分中是 Restaurant 类型,而在另一项中是 bar 类型,这样这些 linting 错误就会消失。

【问题讨论】:

  • 下面的语法呢? :renderItem = (item: Restaurant | Bar) => { return ...}
  • 这看起来不像'OOPish'。 Restaurant 和 Bar 使用方法 render() 实现公共接口怎么样?这两个类都有自己的实现或render()。那么这个方法将简单地在renderItem中引用。

标签: typescript typescript-typings react-tsx typescript-types typescript2.8


【解决方案1】:

您可以做一个简单的比较对象的键/值,这样您就可以知道当前项目的属性 servingFood 是否存在。如果值是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
  ))

【讨论】:

    【解决方案2】:

    您可以使用类型保护来缩小参数的类型。

    您可以使用基于servesFood 字段的可区分联合:

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

    或者,如果接口不共享 servesFood,您可以使用 in 类型保护

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

    【讨论】:

      猜你喜欢
      • 2021-12-12
      • 2020-07-27
      • 2021-07-04
      • 2020-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-11
      相关资源
      最近更新 更多