I would like to make an abstract method that returns 2 different types.
It seems with my implementation typescript is expecting an intersection type of the 2 types, however I would like to have a union type of the 2 types: either one or the other.
This is my implementation:
export type ResponseByCategory = {
cat_a: string,
cat_b: number
}
export enum Category {
cat_a = 'cat_a',
cat_b = 'cat_b'
}
export type Response<C extends Category> = {
[c in Category]: ResponseByCategory[c]
}[C]
export function method<C extends Category>():Response<C>{
const rand = Math.floor(Math.random()*2);
switch(rand){
case 0:{
const a:Response<Category.cat_a> = 'A';
return a;
// ^
// | Type 'string' is not assignable to type 'never'
}
default:{
const b:Response<Category.cat_b> = 1;
return b;
// ^
// | Type 'number' is not assignable to type 'never'
}
}
}
export const a = method<Category.cat_a>(); // Typescript knows a is a string
export const b = method<Category.cat_b>(); // Typescript knows b is a number
With this approach I got the errors when trying to return one or the other type. Typescript is expecting a type never
to be returned, that is the intersection of string
and number
.
Is there a way for Typescript to infer the type I want to return, either one or the other according with the generic type defined in the method?
Of course, this is an oversimplified version of my application. I cannot return a simple union type and I must have some sort of abstraction that can handle lots of different categories.