TypeScript:使用泛型方法从非泛型类获取字段值,无需强制转换

问题描述 投票:0回答:1

我有一个非通用的单例类(例如服务)。 它有一组字段,其类型是泛型类型的后代。 我想在该类上实现一种通用方法,该方法具有选择其中一个字段的关键参数。 然而,此方法应该返回通用祖先。 租赁公司和车辆的人为示例:

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>;
  }
}

我怎样才能正确地做到这一点而不需要投射?

typescript generics singleton
1个回答
0
投票

通用类型

T
可能具有
Car
Truck
的类型,但它也可能具有非常不同的类型。

例如,您可以声明

class Bus extends Vehicle {
}

并将其作为通用参数传递。在这种情况下,函数的返回值将与预期的函数结果不兼容。

强制转换不是出路,因为这样做,你的函数返回类型可能与实际结果不匹配。

有不同的方法来处理这个问题。

您可以像在 Works 示例中那样使用类型联合。

处理此问题的另一种类似方法是返回条件类型作为结果:

getGenericVehicleListOfType<T extends Vehicle>(type: VehicleType): T extends Car ? VehicleList<Car> : VehicleList<Truck> {
  ...
}

但我建议你反对它并坚持使用类型联合作为你的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.