从动物界面和我的农场中的动物图开始:
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.edible}}
(例如使用angular)和所有其他预期的对象属性。这是我不能做的-
export class AnimalOven{
constructor() {
const donald = bigField.pond.donald;
}
}
错误是Property 'donald' does not exist on type 'Animal | Farmland'. Property 'donald' does not exist on type 'Animal'
。 (构建应用程序时,角度编译器也会抛出此错误。)
打字稿显然知道bigField.pond
可能 是农田(具有字符串索引) 或 动物,所以我不确定为什么它不能在这里推断正确的类型。简而言之:
使用 strong-type 和{[key:index]: strong-type 的类型联合时,Typescript是否可以正确推断类型}?
(显然,可能会有更好的方法来创建我的农场和动物,使用键,适当使用数组;但是这里的问题确实与地图类型的 Typescript推断有关)
谢谢。
答案 0 :(得分:0)
通过声明它为FarmlandOrAnimalMap
,您告诉编译器该变量的内容比此处的实际内容更为通用。
如果删除bigField
的类型注释,则将在派生整个对象树的类型时起作用。
对于任何类型FarmlandOrAnimalMap
的变量,除非引入其他检查,否则编译器将永远无法推断属性是Animal
还是Farmland
。