I would like to pass a generic so i can pre-type my returned class.
public createVehicle<O extends AbstractVehicle>(
type: string
): O {
switch (type) {
case "Car":
return new Car(param1, param2);
case OfferType.Sale:
return new Bike(param3, param4)
default:
throw new Error("Vehicle type not supported");
}
}
however this gives me:
Type 'Car' is not assignable to type 'O'.
'Car' is assignable to the constraint of type 'O', but 'O' could be instantiated with a different subtype of constraint 'AbstractVehicle'
which i kind of understand as it can be something like AbstractVehicle & {} but shouldn't this just be an easy thing to do?
Tried for hours without solution, it keeps throwing that error. any suggestions to keep this simple and readable?
Your function is not generic over its return type. You should just write
createVehicle(type: string): Car | Bike
or
createVehicle(type: string): AbstractVehicle
and call it as createVehicle("Car") as Car not createVehicle<Car>("Car").
If anything, your function is generic over its argument type, and you can infer the return type from that:
public createVehicle<T extends "Car" | "Bike">(type: T): T extends "Car" ? Car : T extends "Bike" ? Bike : never
This will infer the correct result type for the call createVehicle("Car") (i.e. typeof createVehicle<"Car">("Car") = Car), but for createVehicle(unknownType) it will still infer the union.