I am trying to make a 'switcher' of an unknown type coming from a database. Basically, there are certain calculation types that have a different data structure and need to be processed differently depending on the type. My first way to solve the problem was using conditionals:
type CalculationTypes = "add" | "average"
export interface Calculation<T extends CalculationTypes> {
calculationID: string // unique to all calculations
type: T
payload: T extends "add" ? CalculationAdd : CalculationAverage
}
interface CalculationAdd {
addlist: {referenceContainer: string, referenceID: string}[]
}
interface CalculationAverage {
averageList: number[]
}
This worked - kind of - because the type wasn't being detected later in the script. I had to infer it, which isn't so bad, but I'm sure there's a better way to do it where the transpiler can automatically deduce the type...
Then later in the script:
for (const calculation of dbresult.calculations) {
switch(calculation.type) {
case "add":
const payload = calculation.payload as CalculationAdd // <--- this is what I want it to do automatically.
/** The transpiler does not detect it. It thinks that payload is of
type CalculationAdd | CalculationAverage **/
payload.addList // do stuff works now with type inference
// do more stuff
break;
case "average":
const payload = calculation.payload as CalculationAverage
payload.averageList // do stuff
// do more stuff
break;
}
}
Without type inference, typescript gives me the error:
Property 'addList' does not exist on type 'CalculationAdd | CalculationAverage'.
Property 'addList' does not exist on type 'CalculationAverage'
So for some reason, typescript has not deduced that it has to be of type CalculationAdd without type inference, even though that's the only possibility given the conditional I set up in the Calculation interface.
How can I change the way I'm defining these types and interfaces so that typescript automatically deduces them?
Thanks!