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
。这对于我的用例来说不是问题,因为在我的代码库中,没有比implements
IVehicle
更能扩展类的情况了。我猜有一个修复方法是
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);