Promise.allSettled() 响应的类型错误

Cas*_*roh 4 javascript node.js typescript

我最近一直在尝试在带有 Typescript 的 NodeJS 上使用 Promise.allSettled,但我遇到了响应问题。allSettled 方法返回一个带有status: "rejected" | "fulfilled"和 值的数组,以防它被满足。问题是,当我尝试访问响应的值时,出现以下错误:

Property 'value' does not exist on type 'PromiseSettledResult<unknown>'.
Property 'value' does not exist on type 'PromiseRejectedResult'.ts(2339)
Run Code Online (Sandbox Code Playgroud)

下面我将留下一个简单的例子,以便您可以复制代码并自己尝试:

const p1 = Promise.resolve(50); 
const p2 = Promise.resolve(100); 

const promiseArray = [p1, p2]; 
  
Promise.allSettled( promiseArray ). 
  then( results => results.forEach( result =>  
    console.log(result.status, result.value)));
Run Code Online (Sandbox Code Playgroud)

如果我在我的项目上运行此代码,我会收到一个错误,因为result.value最后。

我在 Windows 上的版本 12.18.3 上运行我的节点,并且我已将目标设置tsconfig.jsonES2020能够使用该方法本身。

Cas*_*roh 23

@jonrsharpe 回答说:您只有一个状态已满足的值属性,并且您没有检查它。

因此,使用我自己的示例,可以将其修复如下:

const p1 = Promise.resolve(50); 
const p2 = Promise.resolve(100); 

const promiseArray = [p1, p2]; 
  
Promise.allSettled( promiseArray ). 
  then( results => results.forEach( result =>  
    console.log(result.status,
                result.status === 'fulfilled' && result.value
    );
  ));
Run Code Online (Sandbox Code Playgroud)

它现在验证承诺是否已履行,然后打印该值(如果是的话)。


Арт*_*нев 7

在过滤器承诺数组的情况下出现相同的错误:

const promises = ids.map((id) => <some BE API call>);
const resolvedPromises = await Promise.allSettled(promises);
resolvedPromises.filter(({ status }) => status === 'fulfilled').map((p) => p.value);
Run Code Online (Sandbox Code Playgroud)

错误截图

问题是allSettled回报PromiseSettledResult,这是不是在所有出口(我在lib.es2020.promise使用tsconfig):

interface PromiseFulfilledResult<T> {
    status: "fulfilled";
    value: T;
}

interface PromiseRejectedResult {
    status: "rejected";
    reason: any;
}

type PromiseSettledResult<T> = PromiseFulfilledResult<T> | PromiseRejectedResult;
Run Code Online (Sandbox Code Playgroud)

并且.map不明白所有的rejected承诺都是在filtered方法中过滤的。

因此,我什至无法导入类型并将值转换为它们。

作为临时解决方案,我用注释抑制了 ESLint 和 TSC 规则:

  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
Run Code Online (Sandbox Code Playgroud)

然后我PromiseFulfilledResult在项目中创建了相同的接口并使用了类型转换:

resolvedPromises.filter(({ status }) => status === 'fulfilled').map((p) => (p as PromiseFulfilledResult).value);
Run Code Online (Sandbox Code Playgroud)

结果我摆脱了错误和忽略注释的 ESLint/TS 规则。


小智 6

如果在调用该方法后进行类型声明,则可以避免此错误allSettled。例如,您可以立即输入打字稿的类型,如下所示:

const promises = await Promise.allSettled([
  fetch(url).then((response) => response.json()),
  fetch(url).then((response) => response.json()),
]) as {status: 'fulfilled' | 'rejected', value: SomeType}[];
Run Code Online (Sandbox Code Playgroud)

之后它将正常工作:

const resolvedPromises = promises.filter(({ status }) => status === 'fulfilled');
const responses = resolvedPromises.map((promise) => promise.value);
Run Code Online (Sandbox Code Playgroud)