Commencing with an Animal interface and a detailed map of animals residing on my farm:
export interface Animal {
species: string;
edible: boolean;
}
export interface FarmMap{
[key: string]: Animal;
}
Everything seems to be running smoothly. Here is the current state of my farm -
const farm: FarmMap = {
bob: { species: 'sheep', edible: true },
daisy: { species: 'cow', edible: true }
}
Now, I have divided my farm into smaller sections, and I need a new type that can contain either the animals or these sections:
export interface FarmOrAnimalSection {
[key: string]: Animal | FarmMap;
}
const largeField: FarmOrAnimalSection = {
bob: { species: 'sheep', edible: true },
daisy: { species: 'cow', edible: true },
pasture: {
jack: { species: 'dog', edible: false }
},
pond: {
donald: { species: 'duck', edible: true }
},
farmhouse: {
hernietta: { species: 'monkey', edible: false }
}
};
This arrangement appears to be functioning as intended - I can easily access
{{largeField.pond.donald.edible}}
(using for example angular) and all other expected object properties within my markup. However, there is a limitation -
export class Oven{
constructor() {
const donald = largeField.pond.donald;
}
}
An error is triggered stating
Property 'donald' does not exist on type 'Animal | FarmMap'. Property 'donald' does not exist on type 'Animal'
. (This same error will also arise when building the application using an angular compiler.)
It is evident that Typescript recognizes that largeField.pond
could potentially be a FarmMap (due to its string index) or an Animal, but it struggles to infer the correct type in this scenario. To sum up:
Is there a method for Typescript to accurately deduce type when utilizing a union type of specific-type and {[key:index]: specific-type} ?
(Certainly, there might be more effective approaches for organizing my farm and animals, implementation of keys, appropriate utilization of arrays; nevertheless, the focus here primarily revolves around Typescript inference of map types)
Thank you.