【问题标题】:Typescript promise generic type打字稿承诺泛型类型
【发布时间】:2016-12-10 18:23:53
【问题描述】:

我有一个示例 Promise 函数,如下所示。成功时返回number,失败时返回string。编译器抱怨为 promise 指定某种泛型类型。在这种情况下,我必须指定什么类型?我是否必须指定 Promise<number>Promise<number | string>

function test(arg: string): Promise {
    return new Promise((resolve, reject) => {
        if (arg === "a") {
            resolve(1);
        } else {
            reject("1");
        }
    });
}

【问题讨论】:

  • 你试过Promise<number|string>吗?
  • 这样做不会抱怨。这是正确的做法吗?可以同时指定resolve和reject的类型吗?

标签: generics typescript


【解决方案1】:

Promise 的泛型类型应该对应于函数的非错误返回类型。该错误隐式属于 any 类型,并且未在 Promise 泛型类型中指定。

例如:

function test(arg: string): Promise<number> {
    return new Promise<number>((resolve, reject) => {
        if (arg === "a") {
            resolve(1);
        } else {
            reject("1");
        }
    });
}

【讨论】:

  • 有没有办法指定错误案例的类型?例如。我有一个承诺,如果拒绝,则使用自定义对象拒绝。我可以使用Promise&lt;T&gt; 内置泛型类型指定拒绝值的类型吗?谢谢!
  • @tonix 您拒绝自定义对象的确切原因(这样做的灵活性)是因为Promise 具有any 错误类型。不能限制错误类型,因为承诺中的任何运行代码都可以抛出任何东西,而不仅仅是正常的Error。 (见developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…。它是throw expression)。由于 Promise 是一个通用对象,它无法控制其中运行的内容,并且期望您(开发人员)控制其中运行的内容也是乏味/过度期望,因此无法限制错误类型。
  • @GeorgePantazes :我不相信如果可以可选地指定拒绝类型会很乏味。此外,我们也无法控制解析值内部运行的内容,但仍然可以指定它。
【解决方案2】:
function test(arg: string) {
   return new Promise((resolve: (value: number) => void, reject) => {
    if (arg === "a") {
        resolve(1);
    } else {
        reject("1");
    }
  });
}

【讨论】:

  • 只有代码的答案通常可以通过添加一些关于它们的工作方式和原因的解释来改进。在为具有已接受答案的旧问题添加答案时,这一点更为重要。指出您的答案所针对的问题的哪些新方面,并注意时间的流逝和新版本的推出是否会影响答案。
【解决方案3】:

另一种解决方案

附注(顺便说一句)

通用类型“Promise”需要 1 个类型参数。ts(2314)

function test(arg: string){
    return new Promise<number>((resolve, reject) => {
        if (arg === "a") {
            resolve(1);
            // (parameter) resolve: (value: number | PromiseLike<number>) => void
        } else {
            // (parameter) reject: (reason?: any) => void
            reject("1");
        }
    });
}

【讨论】:

    【解决方案4】:

    您可以定义一个自定义的 Promise 类型,它实际上也关心拒绝的类型。你也可以只给它一个类型,拒绝类型将是any,就像在正常的承诺中一样。

    
    type CustomPromise<T, F = any> = {
        catch<TResult = never>(
            onrejected?: ((reason: F) => TResult | PromiseLike<TResult>) | undefined | null
        ): Promise<T | TResult>;
    } & Promise<T>;
    
    function test(arg: string): CustomPromise<number, string> {
        return new Promise((resolve, reject) => {
            if (arg === "a") {
                resolve(1);
            } else {
                reject("1");
            }
        });
    }
    
    const myPromise = test("a");
    myPromise.then((value) => {}); //value is of type `number`
    myPromise.catch((reason) => {}); //reason is of type `string`
    

    【讨论】:

      猜你喜欢
      • 2017-05-16
      • 1970-01-01
      • 2021-11-26
      • 2019-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-29
      相关资源
      最近更新 更多