我有一个非通用的单例类(例如服务)。 它有一组字段,其类型是泛型类型的后代。 我想在该类上实现一种通用方法,该方法具有选择其中一个字段的关键参数。 然而,此方法应该返回通用祖先。 租赁公司和车辆的人为示例:
const enum VehicleType {
Car,
Truck,
}
class Vehicle {
type: VehicleType;
}
class Car extends Vehicle {
}
class Truck extends Vehicle {
}
class VehicleList<T extends Vehicle> {
type: VehicleType;
availableArray: T[];
}
class CarList extends VehicleList<Car> {
}
class TruckList extends VehicleList<Truck> {
}
class RentalCompanyAssets {
cars: CarList;
trucks: TruckList;
// Does not work as cannot match type to generic parameter
getGenericVehicleListOfType<T extends Vehicle>(type: VehicleType): VehicleList<T> {
return type === VehicleType.Car ? this.cars : this.trucks;
}
// Works but needs to be cast to generic type in calling function (see below)
getVehicleListOfType(type: VehicleType): CarList | TruckList {
return type === VehicleType.Car ? this.cars : this.trucks;
}
}
我(可能)可以通过使用非泛型
getVehicleListOfType
但在调用函数中转换返回值来使其工作:
class VehicleTypeAllocator<T extends Vehicle> {
type: VehicleType;
assets: RentalCompanyAssets;
getVehicleList(): VehicleList<T> {
return this.assets.getVehicleListOfType(this.type) as unknown as VehicleList<T>;
}
}
我怎样才能正确地做到这一点而不需要投射?
通用类型
T
可能具有 Car
或 Truck
的类型,但它也可能具有非常不同的类型。
例如,您可以声明
class Bus extends Vehicle {
}
并将其作为通用参数传递。在这种情况下,函数的返回值将与预期的函数结果不兼容。
强制转换不是出路,因为这样做,你的函数返回类型可能与实际结果不匹配。
有不同的方法来处理这个问题。
您可以像在 Works 示例中那样使用类型联合。
处理此问题的另一种类似方法是返回条件类型作为结果:
getGenericVehicleListOfType<T extends Vehicle>(type: VehicleType): T extends Car ? VehicleList<Car> : VehicleList<Truck> {
...
}
但我建议你反对它并坚持使用类型联合作为你的解决方案。