I am struggling to automatically infer the type of different kind of items based on their geometry (in the context of displaying some GeoJSON data).
I am using a generic types, therefore I did not manage to set a custom typeguards, since it would allow me to distinguish "Individual" items from "Aggregates", but not different type of "Individual" items.
Basically, I need to level of inference:
- discriminating Individual items from Aggregates
- discriminating different geometries within each category.
I've created a simplified example, in my real app I have 4 different types of items which may have different possible geometries.
Here is a TypeScript playground, and the code below:
type A = {type: "A", a: string}
type B = {type: "B", b: string}
type C = {type: "C", c: string}
type Geometries = A | B | C
type IndividualFeature<G extends A | B = A | B> = { geometry: G, indivAttribute: string}
type AggregateFeature = { geometry: C, aggAttribute: string}
type DisplayableFeature = IndividualFeature | AggregateFeature
const display = (feature: DisplayableFeature) => {
switch(feature.geometry.type) {
case "A":
console.log("type A", feature.geometry.a, feature.indivAttribute);
return;
case "B":
console.log("type B", feature.geometry.b, feature.indivAttribute)
return;
case "C":
console.log("type C", feature.geometry.c, feature.aggAttribute)
default:
// should not happen
}
}
const indivFeature: IndividualFeature = { geometry: { type: "A", a: "a"}, indivAttribute: "hello indiv"}
const aggFeature: AggregateFeature = { geometry: { type: "C", c: "c"}, aggAttribute: "hello agg"}
The geometry is correctly discriminated, but not individually vs aggregates (the feature.indivAttribute
/feature.aggAttribute
trigger an error).
For the record, I've tried a typeguard: this allows me to differentiate "Indiv" and "Aggregates", but I've lost the discrimination of the geometry.
How should I structure my types/code so feature.indivAttribute
is correctly recognized as a valid attribute in this example?