Typescript Typescipt泛型-返回具有相同泛型参数类型的新实例
假设我有一个从某个接口继承的两个类:(为了简单而精简)Typescript Typescipt泛型-返回具有相同泛型参数类型的新实例,typescript,generics,Typescript,Generics,假设我有一个从某个接口继承的两个类:(为了简单而精简) 接口IVehile{} 类Car实现IVehile{ 构造函数(公共颜色:字符串){} } 类直升机实现IVehille{} 现在我有了一个函数,该函数给定一个实例(该类型扩展了IVehichle)将返回同一类型的新实例 功能克隆(元素:T):T{ if(车辆的元素实例){ 归还新车(元素.颜色); } ... 返回元素; } 克隆(新直升机()) 但是,我在归还新车(…)时出错,说: 'Car' is assignable to th
接口IVehile{}
类Car实现IVehile{
构造函数(公共颜色:字符串){}
}
类直升机实现IVehille{}
现在我有了一个函数,该函数给定一个实例(该类型扩展了IVehichle
)将返回同一类型的新实例
功能克隆(元素:T):T{
if(车辆的元素实例){
归还新车(元素.颜色);
}
...
返回元素;
}
克隆(新直升机())
但是,我在归还新车(…)
时出错,说:
'Car' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'IVehicle'
这似乎不正确,因为的实例应该是T
属于子类型Car
的资产,对吗
之后,我尝试将返回类型转换为类型T
,将returnnewcar(element.color)转换为T代码>
但这会产生以下错误:
Conversion of type 'Car' to type 'T' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
并包括第一个错误
TypeScript是否发现了合法的类型问题,或者这是一个错误?我是否缺少类型约束中的某些内容?如何修复此错误?如果您打算克隆iHicle的实例,我认为将此操作添加到接口本身是一个很好的解决方案
interface IVehicle<ActualType> {
clone(): ActualType;
}
class Car implements IVehicle<Car> {
constructor(public color: string) {}
clone(): Car {
return new Car(this.color);
}
}
class Helicopter implements IVehicle<Helicopter> {
clone(): Helicopter {
return new Helicopter();
}
}
const h = new Helicopter();
const hClone = h.clone();
如果元素
扩展了汽车
,但不是汽车
本身,那么您无法返回新车
。例如:类BetterCar扩展了Car{}
@zerkms,这很有趣。我不知道somebettercaristance instanceof Car
返回了true
。这对于我的用例来说不是问题,因为在我的代码库中,没有比implementsIVehicle
更能扩展类的情况了。我猜有一个修复方法是element.constructor.name==“Car”
,但是Typescript没有注意到这一点?有没有一种简单的方法可以安全地键入此内容?或者是/@ts ignore
?这是一个很好的解决方案,但是,如果类声明不可编辑,例如在库后面,则此重构是不可能的。
interface IVehicle {}
class Car implements IVehicle {
constructor(public color: string) {}
}
class Helicopter implements IVehicle {}
function clone(element: Car): Car;
function clone(element: Helicopter): Helicopter;
function clone(element: IVehicle): IVehicle {
if (element instanceof Car) {
return new Car(element.color);
} else if (element instanceof Helicopter) {
return new Helicopter();
} else {
throw new Error("Unknown subclass of IVehicle passed to clone " + element)
}
}
const h = new Helicopter();
const h1 = clone(h);