I try to declare a recursive type with following interface
interface Map<T> {
[key: string]: Map<T> | T;
}
However, when I try to get property of this object:
const map: Map<number> = {
a: {
b: {
c: 2
}
}
};
console.log(map.a.b.c);
I get an error:
TS2339:Property 'b' does not exist on type 'number | Map<number>'. Property 'b' does not exist on type 'number'.
I understand why it happens, but is there a workaround?
PS My tsconfig.json
is following:
{
"compilerOptions": {
"declaration": true,
"downlevelIteration": true,
"importHelpers": true,
"lib": [
"dom",
"es2017"
],
"module": "es2015",
"moduleResolution": "node",
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"sourceMap": true,
"strict": true,
"target": "es5",
"typeRoots": [
"node_modules/@types"
]
}
}
An indexable type isn't aware of what keys it has, so you cannot use the dot notation, instead, you'll need to use:
console.log(map["a"]["b"]["c"]);
Notice however that the type for map["a"]["b"]
is any
, you'll need to use (map["a"] as MyMap<number>)["b"]
to get the right type.
You shouldn't be using the name Map
for your interface because there's now a built-in type called Map ( type definition ).
If the example you posted really shows your use case then I suggest that you don't annotate the map
variable at all:
const map = {
a: {
b: {
c: 2
}
}
};
console.log(map.a.b.c); // this is fine now
The compiler is smart enough to infer the type of map
to:
type map = {
a: {
b: {
c: number;
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.