user10717747
user10717747

Reputation:

Map of Maps in Typescript / ECMAScript

This is what i personally would consider correct in various languages, but here it is not. I must be ignorant of an aspect of Typescript, but I can not so easy determine where the gap is.

The implementation requires a map of maps. The top map is a string key, and the a map of string-keys and string-values.

class aClass
{
    myMap: Map<string, Map<string, string>>;

    constructor ()
    {
        this.myMap = new Map<string, Map<string, string>>([
            ["key1", new Map<string,string>()],
            ["key2", new Map<string,string>()]
        ]);
    }

    async aTask(map: Map<string,string>)
    {
        map.set("subKey1", "VALUE");
    }

    async someWork()
    {
        this.aTask(this.myMap["key1"]);
        this.aTask(this.myMap.get("key1"));
    }
}

How do I correctly access the Map<string, string>() in the function someWork() ?

The error for the first accessor : this.aTask(this.myMap["key1"]);

Element implicitly has an 'any' type because type 'Map<string, Map<string, string>>' has no index signature. Did you mean to call 'get'?

The error for the second accessor : this.aTask(this.myMap.get("key1"));

Argument of type 'Map<string, string> | undefined' is not assignable to parameter of type 'Map<string, string>'. Type 'undefined' is not assignable to type 'Map<string, string>'.

Upvotes: 2

Views: 10824

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370779

Maps, despite being objects, don't put their values onto properties of the Map instance, which is why this.myMap["key1"] doesn't work.

TypeScript doesn't let you do

this.aTask(this.myMap.get("key1"));

because the .get does not guarantee that the key exists in the Map; it's warning you that it might have returned undefined. To be type-safe, do:

async someWork() {
    const val = this.myMap.get("key1");
    if (val) {
        this.aTask(val);
    }
}

Upvotes: 2

Related Questions