Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript-推断强类型递归索引类型_Typescript_Typescript Typings - Fatal编程技术网

Typescript-推断强类型递归索引类型

Typescript-推断强类型递归索引类型,typescript,typescript-typings,Typescript,Typescript Typings,从动物界面和“我的农场”中的动物地图开始: export interface Animal { type: string; edible: boolean; } export interface Farmland{ [key: string]: Animal; } 一切都很好。这是我的农场- const farm: Farmland = { bob: { type: 'sheep', edible: true }, daisy: { type: 'cow', edi

动物界面和“我的农场”中的动物地图开始:

export interface Animal {
   type: string;
   edible: boolean;
}
export interface Farmland{
   [key: string]: Animal;
}
一切都很好。这是我的农场-

const farm: Farmland = {

  bob: { type: 'sheep', edible: true },
  daisy: { type: 'cow', edible: true }

}
现在,我的法恩可能有一些较小的部分,我想要一个新的类型,将包含动物或这些部分:

export interface FarmlandOrAnimalMap {
  [key: string]: Animal | Farmland;
}

const bigField: FarmlandOrAnimalMap = {

  bob: { type: 'sheep', edible: true },
  daisy: { type: 'cow', edible: true },

  pasture: {
    jack: { type: 'dog', edible: false }
  },
  pond: {
    donald: { type: 'duck', edible: true }
  },
  farmhouse: {
    hernietta: { type: 'monkey', edible: false }
  }
};
这似乎也行得通——我可以很高兴地引用
{{{bigField.pond.donald.aubible}}
(使用例如angular)和标记中所有其他预期的对象属性。以下是我不能做的-

export class AnimalOven{

  constructor() {

    const donald = bigField.pond.donald;

  }
}
错误是,
属性“donald”在类型“Animal | Grands”上不存在。类型“Animal”上不存在属性“donald”
。(当我构建应用程序时,角度编译器也会抛出此错误。)

Typescript显然知道bigField.pond可能是农田(带字符串索引)或动物,因此我不确定它为什么不能推断出正确的类型。简言之:

当使用强类型和{[key:index]:强类型}的类型联合时,Typescript有没有正确推断类型的方法?

(显然,可能有更好的方法来创建我的农场和动物,使用键,适当地使用数组;但这里的问题实际上与地图类型的Typescript推断有关)


谢谢。

通过将其声明为
FarmlandOrAnimalMap
可以告诉编译器变量的内容比这里实际的内容更通用

如果去掉
bigField
的类型注释,这将在派生整个对象树的类型时起作用


对于任何类型的
FarmlandOrAnimalMap
变量,编译器永远无法推断属性是
Animal
还是
Grandland
,除非引入额外的检查。

这感觉像是一个XY问题:您在这里做的是混淆了类型:您的密钥是动物还是“区域”在农场?也许你应该把这些区域作为动物的财产来储存。要从农田中的某个区域生成动物列表,您可以使用
.filter()
检索它们。当然,你可以通过告诉TypeScript你“知道”键是什么来做这件事,也就是说,
constdonald=(bigField.pond作为记录),但我认为这是一种代码味道。谢谢,是的,整个农场的事情是一种试图描述问题的方式,本质上,typescript似乎无法与强类型和{[key:index]:强类型}的联合一起工作-这就是我试图弄清的问题。我将对问题进行编辑以反映这一点。您考虑过使用原子化数据结构吗?大概是这样的: