首页 > 解决方案 > 打字稿:为什么 PromiseLike 在异步函数的对象中可能是 this 的类型?

问题描述

我写了这个函数,但它抛出一个错误,我不明白为什么......

const createObject = async (): Promise<MyType> => {
  await Promise.resolve();
  return {
    async foo() {
      await this.bar();
      // do something else
    },
    async bar() {
      await Promise.resolve();
      // do something here
    }
  };
};

interface MyType {
  foo: () => Promise<void>;
  bar: () => Promise<void>;
}

为什么第 5 行的函数调用this.bar()显示错误?它告诉我它this是 typeMyType还是 a PromiseLike<MyType>。第二种可能的类型是问题,但我看不出在哪种情况下这可能是PromiseLike?难道它不能假设如果调用该函数,这总是一个“加载”object吗?

最优雅的方法是什么?目前我正在这样做(这绝对是丑陋的,作为代码的读者无法理解):

await (await this).bar();

我还发现设置函数的返回类型createObjectfromPromise<MyType>可以Promise<any>解决问题,但这不是很准确。

标签: typescript

解决方案


由于createObject是一个返回的异步函数Promise<MyType>,因此其中的 return 语句可以是 returnPromise<MyType>MyType. 任何一个都是有效的。所以当你直接返回一个对象字面量时,打字稿会有点违反直觉地推断出对象的类型是Promise<MyType> | MyType,并this相应地键入。

如果对象文字直接在返回中,则无法更改此设置。您可以做的是使用中间变量。这个变量将是独立的类型,然后将根据返回类型进行检查:



const createObject = async (): Promise<MyType> => {
  await Promise.resolve();
  let result: MyType = {
    async foo() {
      await this.bar();
      // do something else
    },
    async bar() {
      await Promise.resolve();
      // do something here
    }
  };
  return result;
};

interface MyType {
  foo: () => Promise<void>;
  bar: () => Promise<void>;
}

游乐场链接


推荐阅读