Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/432.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
Javascript 允诺泛型赋值_Javascript_Typescript_Promise - Fatal编程技术网

Javascript 允诺泛型赋值

Javascript 允诺泛型赋值,javascript,typescript,promise,Javascript,Typescript,Promise,请参阅本文末尾列出的代码 我不知道为什么get函数不是强类型的 它被定义为get:id:string=>IPromise 但是,我把它指定为 constructor(srv:Store<TestData>){ this.get = (id) => this.getImp(srv, id); } private getImp(srv:Store<TestData>, d:string) { return srv

请参阅本文末尾列出的代码

我不知道为什么get函数不是强类型的

它被定义为get:id:string=>IPromise

但是,我把它指定为

    constructor(srv:Store<TestData>){
        this.get = (id) => this.getImp(srv, id);
    }

    private getImp(srv:Store<TestData>, d:string) {
        return srv.get("/test")
            .then( (d) => { //d == IPromise<getImp>
                var rep = d.reply; //rep == TestData
                //var rep:string = "" gives error
                return rep;
            });
    }

TypeScript中的泛型具有不同的设计。在某些情况下,它们的类型参数是双变量的,在这种特殊情况下,它们是协变的。承诺是不可变的,所以从某种程度上说,它们应该是协变的,而不是它们所持有的类型

要明白这一点,就要改变

export interface ITest extends TestData

然后删除属性名:string;来自课堂测试。如果您这样做,那么typescript最终会抱怨它无法将IPromise转换为IPromise,因为测试既不能从TestData派生,也不能从TestData派生TestData

此错误的更直接说明:

var x: IPromise<Test> = <IPromise<TestData>><any>{}
编译器认为此代码有效。无论是用T=AB还是T=ABC专门化该类型,都不会改变结果类型的结构,即{x:number}

如果Box中有一个返回Box的方法,会发生什么?让我们添加该方法并查看:

getThis():Box<T> { return this; }
不管专业化程度如何,结果都是一样的

但是,如果我们添加另一个方法,一个重新调用T类型值的方法:

getValue():T { return <T>{}; }
export interface IPromise<T> {
   __bivariance_fix: T;
}
这与专业化T=ABC不兼容

{x: number; y: () => { a: number; b: number; c: number; } }
编译器最终会抱怨

在这一点上,您可能会注意到IPromise实际上并不像Box。实际上,它没有一个返回T类型值的方法,但是它有像then和catch这样的方法,这些方法接受回调,而回调接受T类型的值

then<U>(f: (val: T) => Box<U>): Box<U>;
T=ABC

在本例中,当IB扩展IA时,采用IA类型参数的回调不能安全地替换为采用IB类型参数的回调。与示例中一样,采用IB类型参数的回调可能会尝试调用方法foo,这意味着将IA类型参数传递给该回调将导致类型错误

解决您的问题的最快方法是找到IPromise中返回T类型值的成员:

getValue():T { return <T>{}; }
export interface IPromise<T> {
   __bivariance_fix: T;
}

当然,这会使接口与其他promise类型或库不兼容,因此这里真正的修复方法是让TypeScript纠正回调行为。

TypeScript中的泛型具有不同的设计。在某些情况下,它们的类型参数是双变量的,在这种特殊情况下,它们是协变的。承诺是不可变的,所以从某种程度上说,它们应该是协变的,而不是它们所持有的类型

要明白这一点,就要改变

export interface ITest extends TestData

然后删除属性名:string;来自课堂测试。如果您这样做,那么typescript最终会抱怨它无法将IPromise转换为IPromise,因为测试既不能从TestData派生,也不能从TestData派生TestData

此错误的更直接说明:

var x: IPromise<Test> = <IPromise<TestData>><any>{}
编译器认为此代码有效。无论是用T=AB还是T=ABC专门化该类型,都不会改变结果类型的结构,即{x:number}

如果Box中有一个返回Box的方法,会发生什么?让我们添加该方法并查看:

getThis():Box<T> { return this; }
不管专业化程度如何,结果都是一样的

但是,如果我们添加另一个方法,一个重新调用T类型值的方法:

getValue():T { return <T>{}; }
export interface IPromise<T> {
   __bivariance_fix: T;
}
这与专业化T=ABC不兼容

{x: number; y: () => { a: number; b: number; c: number; } }
编译器最终会抱怨

在这一点上,您可能会注意到IPromise实际上并不像Box。实际上,它没有一个返回T类型值的方法,但是它有像then和catch这样的方法,这些方法接受回调,而回调接受T类型的值

then<U>(f: (val: T) => Box<U>): Box<U>;
T=ABC

在本例中,当IB扩展IA时,采用IA类型参数的回调不能安全地替换为采用IB类型参数的回调。与示例中一样,采用IB类型参数的回调可能会尝试调用方法foo,这意味着将IA类型参数传递给该回调将导致类型错误

解决您的问题的最快方法是找到IPromise中返回T类型值的成员:

getValue():T { return <T>{}; }
export interface IPromise<T> {
   __bivariance_fix: T;
}

当然,这会使接口与其他promise类型或库不兼容,因此这里真正的修复方法是使用TypeScript来纠正回调行为。

then参数d不会是IPromise,但测试是错误的。但是,它将是IGetResult,不???。然后d:IGetResult=>{//d==IPromise仍然,问题仍然是,为什么没有错误是的,srv.get/test:IPromise.然后d:IGetResult=>{//d==IGetResult。很遗憾,我无法回答实际问题,因为我不知道TypeScripts的类型推断功能。then参数d不会是IPromise,但测试是错误的。但是,它将是IGetResult,否???。然后d:IGetResult=>{//d==IPromise仍然存在问题,为什么没有e
erryeah,srv.get/test:IPromise.then d:IGetResult=>{//d==IGetResult。很遗憾,我无法回答实际问题,因为我不知道类型脚本的类型推断能力。协方差和逆变是什么,它们在这里如何应用:P?我刚刚看到Anders对这篇文章的评论。他说我们的类型系统是结构化的,泛型是共变的,但因为参数是na从本质上说是反变的,总的来说,它们最终是双变的。我不确定他说的是什么意思,因为参数自然是反变的。你的答案对语言设计师的评论正确吗?哦,不,我的答案不完全正确。显然规则比我所认为的更复杂,泛型只保留双变变量,直到它们得到输入类型为T的成员字段或返回该类型值的函数。我必须编辑并更新我的答案。只需注意:协变和逆变约束的组合应产生不变量,而不是双变量泛型。它们是双变量的原因是无法对事件侦听器建模类型不同,但那是在字符串类型和联合类型之前什么是协变和逆变以及它们如何在这里应用:P?我刚刚看到Anders对这篇文章的评论。他说我们的类型系统是结构化的,泛型是共变的,但由于参数自然是逆变的,所以它们最终是双变的I’我不知道他是什么意思,因为参数自然是反变的。你的答案与语言设计师的评论相符吗?哦,不,我的答案不完全正确。显然规则比我所认为的更复杂,泛型只有在得到输入类型T的成员字段或函数之前才保持双变量n返回该类型的值。我必须编辑并更新我的答案。请注意:将协变和逆变限制结合起来应该得到不变量,而不是双变量泛型。它们是双变量的原因是,没有其他方法可以对事件侦听器类型建模,但这是在字符串类型和联合类型之前