Is there a way to refactor the code below to eliminate the switch case while maintaining type safety? I've encountered this issue several times and am looking for a pattern that utilizes a map or another approach instead of a switch case.
function translate(when: When): SomeCommonResultType {
switch (when.object) {
case "timespan":
return translateTimeSpan(when);
case "time":
return translateTime(when);
case "datespan":
return translateDateSpan(when);
case "date":
return translateDate(when);
}
}
type When = Timespan | Time | DateSpan | Date;
export interface Timespan {
readonly object: "timespan";
startTime: number;
endTime: number;
startTimezone?: string;
endTimezone?: string;
}
function translateTimeSpan(when: Timespan): SomeCommonResultType {
...
}
export interface Time {
readonly object: "time";
time: number;
timezone: string;
}
function translateTime(when: Time): SomeCommonResultType {
...
}
export interface DateSpan {
readonly object: "datespan";
startDate: string;
endDate: string;
}
function translateDateSpan(when: DateSpan): SomeCommonResultType {
...
}
export interface Date {
readonly object: "date";
date: string;
}
function translateDate(when: Date): SomeCommonResultType {
...
}
I typically avoid using 'any' like this:
const TranslateWhenMap = new Map<string, any>([
["timespan", translateTimeSpan],
["date", translateDate],
["datespan", translateDateSpan],
["time", translateTime],
]);
function translate(when: When): SomeCommonResultType {
return TranslateWhenMap.get(when.object)(when);
}