A function takes an object which can be either of TypeA or TypeB. The first parameter specifies the type of the object. The returned type also depends on this first parameter.
Problem: TypeScript does not infer the type of the object within a case (or within an if). The following code has errors.
I know I can fix this issue by be explicit about the types (add as TypeA) but I wanted to know if there are other solutions to avoid having to put the explicit cast.
type TypeA = {
input: { foo: string }
output: { foo: number }
}
type TypeB = {
input: { bar: string }
output: { bar: number }
}
type Types = {
TypeA: TypeA
TypeB: TypeB
}
type TypesName = keyof Types
/**
* Takes TypeA or TypeB objects, and the return type is based on the type.
*/
function transform<N extends TypesName>(typeName: N, typeValue: Types[N]['input']): Types[N]['output'] {
switch (typeName) {
case 'TypeA':
return transformTypeA(typeValue) // Argument of type '{ foo: string; } | { bar: string; }' is not assignable to parameter of type '{ foo: string; }'.
case 'TypeB':
return transformTypeB(typeValue) // Argument of type '{ foo: string; } | { bar: string; }' is not assignable to parameter of type '{ bar: string; }'.
}
throw new Error('Unknown type')
}
function transformTypeA(typeA: TypeA['input']): TypeA['output'] {
return { foo: parseInt(typeA.foo) }
}
function transformTypeB(typeB: TypeB['input']): TypeB['output'] {
return { bar: parseInt(typeB.bar) }
}
const transformedValue = transform('TypeA', { foo: 'lol' })
console.log(transformedValue) // transformedValue is of type { foo: number }