Typescript 从扩展接口推断属性 背景

Typescript 从扩展接口推断属性 背景,typescript,Typescript,我有以下基本接口: interface IVehicle { readonly id: number; readonly price: number; } 然后这两个: interface ICar { readonly type: 'land'; readonly manufacturers: ICarManufacturer[]; } 车辆只能是汽车或飞机。为了这篇文章的缘故,这些都相当简单 我试过的 为了解决这个问题,我首先扩展了每个“子类”,如: 这可以很好地工作

我有以下基本接口:

interface IVehicle {
  readonly id: number;
  readonly price: number;
}
然后这两个:

interface ICar {
  readonly type: 'land';
  readonly manufacturers: ICarManufacturer[];
}

车辆只能是汽车或飞机。为了这篇文章的缘故,这些都相当简单


我试过的 为了解决这个问题,我首先扩展了每个“子类”,如:

这可以很好地工作,但我还希望能够在我的代码中不知道类型的部分执行以下操作:

const vehicle = getVehicle(id); // Returns a "Vehicle"
if (vehicle.type === 'car') {
  processCarManufacturers(manufacturers); // Fn expects a "Car" - How to infer that type from the "if" above?
我也尝试过泛型,但这似乎是错误的:

interface Vehicle<T extends Car | Vehicle> {...}
interface Car extends Vehicle<Car> {...}
接口车辆{…}
接口车扩展车辆{…}
但即便如此,推论似乎也不是这样的


我希望能够使用
IVehicle
,并通过一些属性推断对象的其余属性-同时,在代码的其他部分,能够使用
ICar
及其所有4个属性


它看起来几乎像某种循环依赖。不确定我是不是要进兔子洞…

你可以让你的
车辆
a类所有可能的车辆简单地结合在一起。这可以像这样工作:

接口车辆{
只读id:数字;
只读价格:数字;
}
接口ICar扩展IVehicle{
只读类型:'land';
只读制造商:ICarManufacturer[];
}
接口IAirplane扩展IVehicle{
只读类型:“air”;
只读制造商:IAirplaneManufacturer[];
}
类型车辆=
|ICar
|飞机
IVehicle
是基础,
ICar
IAirplane
都扩展了它。这确保它们各自具有相同的共享属性
id
price

车辆
类型是
ICar
IAirplane
的联合体。这里重要的是,它们都共享
类型
属性。这使您可以将其作为一个应用程序使用。当你这样做的时候

if(vehicle.type=='land'){
// ...
}
然后在
if
中,车辆只能是一辆汽车,因为它是工会中唯一一个
type
设置为文本
“land”
的成员

因此,如果您的代码如下所示,编译器将接受:

接口ICarManufacturer{tires:boolean;}
接口IAIRPlaneMacturer{wings:boolean;}
接口车辆{
只读id:数字;
只读价格:数字;
}
接口ICar扩展IVehicle{
只读类型:'land';
只读制造商:ICarManufacturer[];
}
接口IAirplane扩展IVehicle{
只读类型:“air”;
只读制造商:IAirplaneManufacturer[];
}
类型车辆=
|ICar
|飞机
const vehicle=getVehicle(id);//返回“车辆”
如果(vehicle.type==='land'){
工艺制造商(车辆制造商);
}

您是否有与接口配套的实现,或者您是否只需要使用类型?@VLAZ,您能详细说明一下吗?不遵循…是否有实现这些接口的实际类?或者你只是做一些类似于
const-plane:IAirplane={type:“air”,manufacturers:[]}
-使用普通对象的类型?@VLAZ,啊,就是后者。太好了,谢谢。答案取决于它,我所想到的最简单的一个方法只适用于类型。给我几分钟,谢谢!我希望有一种只使用接口的方法,但这也很好。干杯
const vehicle = getVehicle(id); // Returns a "Vehicle"
if (vehicle.type === 'car') {
  processCarManufacturers(manufacturers); // Fn expects a "Car" - How to infer that type from the "if" above?
interface Vehicle<T extends Car | Vehicle> {...}
interface Car extends Vehicle<Car> {...}