Skip to content Skip to sidebar Skip to footer

Why Am I Getting "type 'string[] | Undefined' Is Not An Array Type." For My Object Variable?

I am trying to create a state variable named hidden to be a dictionary (ex: [{'cutomkey1':'somevalue', 'customkey2':'somevalue'}]). hidden can be empty [{}]. In one of my methods I

Solution 1:

The declaration hidden?: Array<String>, means that the property could either be a Array<String> OR undefined.

Using the property like this will fail:

hidden.push(item)

because hidden could be undefined (and undefined has no property push).

If you check if this.state.hidden is available, typescript won't complain anymore:

if(this.state.hidden)
  this.setState({
              hidden: [...this.state.hidden, {dict}]
          })

or you can provide a default value using nullish concealing:

...(this.state.hidden ?? [])

Solution 2:

If you read attentively the code that creates your 'hidden' array ,

if (this.state.hidden) {
            this.setState({
                hidden: [...this.state.hidden, {dict}]
            })
        }

you can see that you spread the state.hidden elements (no pb with those , they already are of the correct type, any type, we don't matter ,as they are coming from a previous well typed and built array ),but, then you add a litteral object who has a property called dict , of type Map<string, string>.

This means your array will contain objects that have a "dict" property respecting this interface :{dict:Map<string,string>} . This is why you have this strange error message about this object litteral with a dict property which does not exist on type string (obviously, the items in your array are not strings)

What you can do is :

  1. type hidden as an Array<{dict:Map<string,string>}>.
  2. spread the content of Map<string,string> inside your array when building it (hidden : [...this.state.hidden,...dict]) , which will leads you to have an Array<Record<string,string>> (Record<K,V> being the type of each key value pair item you have in your Map)
  3. create an interface like :
    interface MyInterface
     { 
      dict:Map<string,string>;
    }

then type your array as Array <MyInterface>

  1. Use the Array.from(dict.entries()) méthod to get an array of tuples ([key:string,value:string]), then use the array map operator to transform your entries into something that feets your needs better in this situation (maybe the string you wanted in the first place) by concatening the key and the value of each tuple item (or anything else that gives you a unique string). In another way, if you just keep the array that you get from "Array.from" , you will have the kind of structure you want (an array of keyValue Pair tuples)

There are lots of other options , but those are the main tracks you can follow . And , at the end , if you really want your "hidden" state variable to be a dictionary ,type it as a Map<string,string> from the beginning , and when you reaffect-it , just do

if (this.state.hidden) {
            this.setState({
                hidden: newMap([...Array.from(this.state.hidden.entries()), ...Array.from(dict.entries())])
            })
        }

You don't have to do all this gym if you target ES6 , as this will work :

if (this.state.hidden) {
            this.setState({
                hidden: newMap([...this.state.hidden, ...dict])
            })
        }

And , BTW , I think when you set the objects in your Map , you want to do dict.set(target.id, parent.id) instead of dict.set(parent.id, parent.id) .If not , what's the point of using a Map here ?

Post a Comment for "Why Am I Getting "type 'string[] | Undefined' Is Not An Array Type." For My Object Variable?"