【问题标题】:How to avoid 'Object is possibly null' warning on properties that will be populated in the future如何避免在将来填充的属性上出现“对象可能为空”警告
【发布时间】:2019-09-15 07:40:16
【问题描述】:

我正在使用带有 vue 的 Typescript。问题是我已经声明了一个名为 categoryList 的实例属性,当组件在运行时使用来自 api 调用的数组呈现时,该属性将被填充。所以,当我在另一个方法中引用这个属性时:

this.categoryList.length && this.categoryList[0] 因为我知道这在方法执行时会有一些价值

TS 给了我一个警告。

由于 categoryList 将是一个 Object 数组,如果我这样访问它

this.categoryList[0].source_id

我收到以下警告

相反,如果我像这样访问它this.categoryList[0]

我收到以下警告

但是,如果将来在运行时将值分配给被引用的实例属性,我该如何避免这种警告。

class Alerts extends Vue {
    private activeView: number = VIEW.NEW; 
    private categoryList: [] = [];

    mounted() {
      this.fetchCategories()
    }

    /*
     * method to fetch from an api call
     */
    fetchCategories() {
      this.$axios.get(CATEGORY_URL).then((res) => {
          categoryList = res.data
      })
    }

    doSomethingWithCategories() {
       // have to use categoryList here
       const use = this.categoryList.length && this.categoryList[0] // This warns me that Object is possibly undefined
       // ...
    }

}

正如@Mark 所建议的,我已经在使用条件来确保值的可用性,但仍然收到警告。

【问题讨论】:

  • 发布您收到的准确和完整的错误/警告。
  • 一方面,您已将您的categoryList 声明为private categoryList: [] = [] 中的一个空数组。那么categoryList = res.data 也应该因为分配无效而给你一个错误(但也可能因为它应该是this.categoryList = res.data)。我们需要查看实际代码(或MCVE),正如 JB 所说,实际错误。
  • 我正在使用 axios 并且 res 的类型为 AxiosResponse<any> 而 res.data 的类型为 any 。因此,将其分配给 categoryList 不会弹出任何警告。
  • 编译器似乎没有考虑布尔运算的左边部分。它确实理解if 块,所以我会尝试将它包含在if(this.categoryList[0] !== undefined) {...} 之类的条件中,甚至可能是if(this.categoryList.length > 0) {...}。也可以使用this.categoryList.forEach(...) 工作,只需获取第一个元素并退出循环。
  • if(this.categoryList.length > 0) {...}if(this.categoryList.length){...} 工作方式相同,因为 0 是 falsey。此外,即使在条件检查中,似乎按索引访问属性也会弹出警告。`this.categoryList.forEach(...)` 似乎有点骇人听闻,但摆脱了警告

标签: typescript vue.js vuejs2 axios


【解决方案1】:

这是你的问题:

 private categoryList: [] = [];

应该是:

 private categoryList: YourDataType[] = [];

当您将数组定义为 [] 类型时,您实际上是在告诉 Typescript,此变量的值将永远是大小为 0 的元组,或 []

【讨论】:

  • 确实如此。通过声明这样的实例属性解决了我的问题:private categoryList: object[] = [];
【解决方案2】:

需要注意的一件有趣的事情:如果您确定 categoryList 在代码执行时会有一个值,那么您可以通过以下 hack 来避免警告。但不建议经常使用它,因为我们应该在需要的地方应用 null/undefined 检查。

this.categoryList![0].source_id

!告诉 typescript 在代码运行时,它前面的对象总是有一个值。

更多信息,请查看this answer

【讨论】:

  • 不应滥用空合并运算符,我认为建议不熟悉 typescript 的人使用它根本不是一个好主意。
  • @PatrickMichaelsen 这就是我写免责声明的原因[但不建议经常使用它,因为我们应该在需要的地方应用空/未定义检查。]!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-18
  • 2019-02-24
  • 2015-05-08
相关资源
最近更新 更多