0

I am using Typescript with vue. The problem is that I have declared an instance property named categoryList which will be populated when the component renders on the runtime with an array from an api call. So, when I am referencing this property in another method like this:

this.categoryList.length && this.categoryList[0] since I know that this will have some value when the method executes

TS gives me a warning.

Since categoryList will be an array of Object, if I access it like this

this.categoryList[0].source_id

I get the following warning

enter image description here

Instead, if I access it like this this.categoryList[0]

I get the following warning

enter image description here

But, how can I avoid this kind of warning for such cases where value will be assigned on run time in the future to an instance property being refernced.

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
       // ...
    }

}

As advised by @Mark, I am already using conditionals to ensure value availability but still getting warning.

enter image description here enter image description here

slumbergeist
  • 1,438
  • 12
  • 18
  • Post the exact and complete error/warning you get. – JB Nizet Apr 25 '19 at 19:48
  • 1
    For one thing, you've declared that your `categoryList` as an empty array in `private categoryList: [] = []`. Then `categoryList = res.data` should also give you an error because of invalid assignment (but probably also because it's supposed to be `this.categoryList = res.data`). We would need to see the actual code (or an [MCVE](https://stackoverflow.com/help/mcve)), and as JB said, the actual error. – p.s.w.g Apr 25 '19 at 19:49
  • I am using axios and res is of type `AxiosResponse` and res.data is of type `any` . So, assigning it to categoryList doesnt popup any warning. – slumbergeist Apr 25 '19 at 20:01
  • The compiler doesn't seem to take into account the left part of the boolean operation. It do understand `if` blocks, so I would try to enclose it in a conditional like `if(this.categoryList[0] !== undefined) {...}` or may be even `if(this.categoryList.length > 0) {...}`. Also may work using `this.categoryList.forEach(...)`, just taking the first element and exiting the loop. – Max Oriola Apr 25 '19 at 20:25
  • `if(this.categoryList.length > 0) {...}` works same as `if(this.categoryList.length){...}` since 0 is `falsey`. Also, seems like accessing the property by index will popup a warning even in the conditional check.` this.categoryList.forEach(...)` seems a bit hackey but get rids of the warning – slumbergeist Apr 25 '19 at 20:33
  • Well, indeed, `forEach` is not a good idea because it can't be stopped. Better this: `for (const categoryItem of this.categoryList) { ...; break; }` – Max Oriola Apr 25 '19 at 21:40

2 Answers2

1

Here is your issue:

 private categoryList: [] = [];

Should be:

 private categoryList: YourDataType[] = [];

When you define an array as type [] you are essentially telling Typescript that the value of this variable will only ever be a tuple of size 0, or [].

  • 1
    indeed, this was the case. Fixed my issue by declaring instance property like this: `private categoryList: object[] = [];` – slumbergeist Apr 26 '19 at 05:25
-1

An interesting thing to note: If you know for sure that categoryList will have a value when code executes, then you can get away with the warning with following hack. But its not advisable to use it often as we should apply null/undefined checks wherever required.

this.categoryList![0].source_id

! tells typescript that the object preceding it will always have a value when the code runs.

For more info, please check this answer.

Krantisinh
  • 1,579
  • 13
  • 16
  • The null coalesce operator shouldn't be abused and I don't think it's a good idea to advise people new to typescript to use it at all. – Patrick Michaelsen Apr 26 '19 at 14:51
  • @PatrickMichaelsen That's why I had written the disclaimer [But its not advisable to use it often as we should apply null/undefined checks wherever required.] ! – Krantisinh Apr 27 '19 at 18:55