我尝试使用以下接口声明递归类型
interface Map<T> {
[key: string]: Map<T> | T;
}
但是,当我尝试获取此对象的属性时:
const map: Map<number> = {
a: {
b: {
c: 2
}
}
};
console.log(map.a.b.c);
我收到错误:
TS2339:Property 'b' does not exist on type 'number | Map<number>'. Property 'b' does not exist on type 'number'.
我明白为什么会这样,但是有解决方法吗?
P.S。我的tsconfig.json
如下:
{
"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"
]
}
}
答案 0 :(得分:2)
indexable type并不知道它有哪些键,所以你不能使用点符号,而是你需要使用:
console.log(map["a"]["b"]["c"]);
请注意,map["a"]["b"]
的类型为any
,您需要使用(map["a"] as MyMap<number>)["b"]
来获取正确的类型。
您不应该为您的界面使用名称Map
,因为现在有一个名为Map(type definition)的内置类型。
如果您发布的示例确实显示了您的用例,那么我建议您根本不对map
变量进行注释:
const map = {
a: {
b: {
c: 2
}
}
};
console.log(map.a.b.c); // this is fine now
编译器非常聪明,可以将map
的类型推断为:
type map = {
a: {
b: {
c: number;
}
}
}