Typescript中的递归类型属性

时间:2017-05-22 18:53:59

标签: typescript

我尝试使用以下接口声明递归类型

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"
    ]
  }
}

1 个答案:

答案 0 :(得分:2)

indexable type并不知道它有哪些键,所以你不能使用点符号,而是你需要使用:

console.log(map["a"]["b"]["c"]);

请注意,map["a"]["b"]的类型为any,您需要使用(map["a"] as MyMap<number>)["b"]来获取正确的类型。

您不应该为您的界面使用名称Map,因为现在有一个名为Maptype 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;
        }
    }
}