I have a type that is deductible from one field of the object.
And I wrote this function that takes the zoneType and returns the associate zone.
But at the end, and on each call I get : MyType1 | MyType2 | MyType3
and not the associated type. This type is actually deductible from the argument, since the switch case can easily find the type.
We are talking about geojson btw.
I was wondering trying overloading, but typescript does not allow having duplicated functions. Also, infer, but it looks "huge" for something that can be guessed by TS itself?
I will appreciate your help.
Thanks !
type MyType1 = "geojson.Feature<geojson.MultiPolygon>";
type MyType2 = "geojson.Feature<geojson.Polygon>";
type MyType3 = "geojson.FeatureCollection<geojson.Polygon>";
export type ZoneGeojson = MyType1 | MyType2 | MyType3;
type InternalZone = {
id: number;
zone: ZoneGeojson | null;
zone_type: ZoneZoneType;
};
export interface Zone1 extends InternalZone {
zone_type: ZoneZoneType.Type1 | ZoneZoneType.Type2;
zone: MyType1 | null;
}
export interface Zone2 extends InternalZone {
zone_type: ZoneZoneType.Type3;
zone: MyType1 | null;
}
export interface Zone3 extends InternalZone {
zone_type: ZoneZoneType.Type4;
zone: MyType1 | null;
}
export const exportZone = (
zoneType: ZoneZoneType,
zone: FeatureCollection<Polygon>,
) => {
switch (zoneType) {
case ZoneZoneType.Type1:
case ZoneZoneType.Type2:
return zone1.zoneGeojsonFactory.exportZoneEdition(zone);
case ZoneZoneType.Type3:
return zone2.zoneGeojsonFactory.exportZoneEdition(zone);
case ZoneZoneType.Type4:
return zone3.zoneGeojsonFactory.exportZoneEdition(zone);
default:
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
throw new Error(`Unknown zone type ${zoneType ?? '[undefined]'}`);
}
};
This is some specific case of return type based on parameter
Applied to your case :
type ObjectType<T> =
T extends ZoneZoneType.Type1 ? Zone1 :
T extends ZoneZoneType.Type2 ? Zone1 :
T extends ZoneZoneType.Type3 ? Zone2 :
T extends ZoneZoneType.Type4 ? Zone3 :
never;
export const exportZoneEditionGeojson = <T extends ZoneZoneType>(
zoneType: T,
zoneEditionGeojson: FeatureCollection<Polygon>,
): ObjectType<T> => {
switch (zoneType) {
case ZoneZoneType.Type1:
case ZoneZoneType.Type2:
return zone1.zoneGeojsonFactory
.exportZoneEdition(zoneEditionGeojson) as ObjectType<T>;
case ZoneZoneType.Type3:
return zone2.zoneGeojsonFactory
.exportZoneEdition(zoneEditionGeojson) as ObjectType<T>;
case ZoneZoneType.Type4:
return zone3.zoneGeojsonFactory
.exportZoneEdition(zoneEditionGeojson) as ObjectType<T>;
default:
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
throw new Error(`Unknown zone type ${zoneType}`);
}
};