Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 回归泛型推理_Typescript_Generics_Type Inference - Fatal编程技术网

Typescript 回归泛型推理

Typescript 回归泛型推理,typescript,generics,type-inference,Typescript,Generics,Type Inference,我正在尝试使用 一般的想法是我有一个IService接口和一个BaseService抽象类。抽象类有一个origin属性,它是IService的一个实例,所有未实现的调用都被转发到此对象BaseService公开一个静态方法wrap,该方法创建装饰器的新实例,并将其源设置为作为参数提供的服务实例 这种方法的功能不是问题,当我尝试指定类型时,问题就出现了。出于某种原因,当我尝试用VerificationService装饰MongoService时,原始类型被减少为iSeries设备,返回值的类型是

我正在尝试使用

一般的想法是我有一个
IService
接口和一个
BaseService
抽象类。抽象类有一个
origin
属性,它是
IService
的一个实例,所有未实现的调用都被转发到此对象
BaseService
公开一个静态方法
wrap
,该方法创建装饰器的新实例,并将其源设置为作为参数提供的服务实例

这种方法的功能不是问题,当我尝试指定类型时,问题就出现了。出于某种原因,当我尝试用
VerificationService
装饰
MongoService
时,原始类型被减少为
iSeries设备
,返回值的类型是
VerificationService&iSeries设备
,而不是所需的
VerificationService&MongoService


我的问题是,这是否是由于代码可能导致的协方差/反方差问题而导致的预期行为,或者这是一个bug,编译器只是不知道参数的类型是MongoService。请注意,当我试图装饰一个没有添加任何属性的类的实例时,类型是正确推断的(第37行)

我不能100%确定为什么会发生这种情况,但是如果您查看
包装器的类型和
验证服务的构造函数(继承自
基本服务
)我们知道为什么会这样。构造函数的参数是
ISerivce
而不是泛型类型,因此最简单的假设是在
wrap
中推断
U
IService
,而
wrap
的第二个参数满足
IService
的要求,因此一切都很好,没有理由进一步研究

最简单的解决方案是更改
包装器的类型,因为参数可以是任何服务:

static wrap<U extends IService, T extends BaseService>(this: { new(origin: IService): T }, origin: U): T & U {
    return new Proxy(new this(origin) as T & U, {
        get(target: T & U, prop: keyof T | keyof U) {
            if (isOverriden(target, prop)) return target[prop];
            return target.origin[prop];
        }
    })
}
// All work as expected
const serviceInferedIncorrectly = VerificationService.wrap(new MongoService()); // VerificationService & MongoService
const serviceInferedCorrectly = VerificationService.wrap(new SimpleService()); // VerificationService & SimpleService
const serviceSpecified = VerificationService.wrap<MongoService, VerificationService>(new MongoService()); // VerificationService & MongoService
static wrap(this:{new(origin:IService):T},origin:U):T&U{
以T&U的形式返回新的代理(新的此(原始){
获取(目标:T&U,道具:T的钥匙| U的钥匙){
if(isOverriden(target,prop))返回target[prop];
返回目标。原点[prop];
}
})
}
//一切按预期进行
const serviceInferedinRightly=VerificationService.wrap(新的MongoService());//验证服务和MongoService
const serviceInferedRightly=VerificationService.wrap(新SimpleService());//验证服务和简单服务
const serviceSpecified=VerificationService.wrap(新的MongoService());//验证服务和MongoService