Typescript + jQuery Promises = .then类型不匹配

时间:2014-08-01 16:00:18

标签: jquery typescript promise

我使用的是Typescript和jQuery Promises,我遇到了以下代码的错误:

    var promiseOne = this.myFunc(1);
    var promiseTwo = this.myFunc(2);

    $.when(promiseOne, promiseTwo).then((valFromPromiseOne: number, valFromPromiseTwo: number) =>   //Error here (see below)
    {
        //Use both return values of the promises...
    });

    myFunc(value: number): JQueryPromise<number>
    {
        var dfd = $.Deferred();

        setTimeout(function ()
        {
            dfd.resolve(value);
        }, 1000);

        return dfd.promise();
    }

我得到的错误是:

    Error   5   Supplied parameters do not match any signature of call target:
        Call signatures of types '(valFromPromiseOne: number, valFromPromiseTwo: number) => void' and '(value: any) => {}' are incompatible:
            Call signature expects 1 or fewer parameters.

我希望只有在两个Promise都被解析时才能执行该函数。

我做错了吗?是否有不同的方式来实现我想要的目标?

由于

4 个答案:

答案 0 :(得分:4)

终于找到了做到这一点的方法。第二个参数必须是可选的。

$.when(promiseOne, promiseTwo).then((valFromPromiseOne: number, valFromPromiseTwo?: number) =>   //valFromPromiseTwo has to be optional
{
    //Use both return values of the promises...
});

在此更改后,它正常工作。

不确定这是不是正确的方法。但它对我有用。

答案 1 :(得分:3)

对于那些仍在尝试从jQuery.d.ts处理此TypeScript编译器错误的人,$ .when上的泛型将需要设置为'any'然后你可以在解析函数参数中添加输入以恢复类型安全(对于那些幸运的人... intellisense)。

    var promiseOne: JQueryPromise<TypeA> = this.myFunc(1);
    var promiseTwo: JQueryPromise<TypeB> = this.myFunc(2);

    $.when<any>(promiseOne, promiseTwo).then((valFromPromiseOne: TypeA, valFromPromiseTwo: TypeB) => {
           //Use both return values of the promises with Type Safety for TypeA and TypeB...
    });

答案 2 :(得分:1)

你是对的,“。d.ts”似乎是不正确的。但是jQuery方式的承诺并不符合Promises / A +。

documentation from jQuery

  

在将多个Deferred对象传递给jQuery.when的情况下,该方法从新的“master”Deferred对象返回Promise,该对象跟踪它已传递的所有Deferred的聚合状态。一旦所有延期解决方案解决,该方法将解决其主延期,或者在其中一个延期被拒绝后立即拒绝主延期。 如果解析了主Deferred,则会传递传递给jQuery的所有Deferred的已解析值。

这不是方法“then()”的正确定义。根据{{​​3}},只应使用第一个参数:

  

2 /如果onFulfilled是一个函数:i /它必须在履行承诺后调用,承诺的值作为其第一个参数

现代浏览器the Promises/A+ spec。应该避免使用jQuery解决方案,首选implement the spec。我建议您阅读compliant polyfill

答案 3 :(得分:0)

虽然@Jonathan Harrison的回答非常正确,但它并没有涵盖所有可能的情况:如果承诺是某种jQuery ajax调用的结果,则接收的值不是单个值,而是一个数组三个要素: - 预期值 - ajax调用的状态 - ajax调用的XHttpRequest对象

所以,这段代码失败了:

var promiseOne: JQueryPromise<TypeA> = $.ajax(...); // or $.get(), $.post()
var promiseTwo: JQueryPromise<TypeB> = this.myFunc(2);

$.when<any>(promiseOne, promiseTwo).then((
  valFromPromiseOne: TypeA, // oops, is an array [TypeA,string, object]
  valFromPromiseTwo: TypeB // yeah, it's TypeB
) => {

});

我发现最好的解决方案是让它编译并使用它是一种自定义类型,如下所示:

type WhenAjaxResponse<T> = [T, string, XMLHttpRequest]

然后,修改这样的代码使其工作:

$.when<any>(promiseOne, promiseTwo).then((
  valFromPromiseOne: WhenAjaxResponse<TypeA>,
  valFromPromiseTwo: TypeB
) => {
  // valFormPromise1[0] is of TypeA
}