简体   繁体   English

Typescript中的递归类型属性

[英]Recursive type properties in Typescript

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: PS我的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"
    ]
  }
}

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. 但是请注意, map["a"]["b"]any ,您需要使用(map["a"] as MyMap<number>)["b"]来获取正确的类型。

You shouldn't be using the name Map for your interface because there's now a built-in type called Map ( type definition ). 您不应该为接口使用名称Map ,因为现在有一个称为Map类型定义 )的内置类型

If the example you posted really shows your use case then I suggest that you don't annotate the map variable at all: 如果您发布的示例确实显示了用例,那么我建议您根本不要注释map变量:

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: 编译器足够聪明,可以将map的类型推断为:

type map = {
    a: {
        b: {
            c: number;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM