Comment utiliser promise.allSettled avec dactylographié?

Nov 20 2020

La construction de Typescript échoue car elle ne semble pas aimer Promise.allSetttledmême si j'ai défini ts config comilerOptions avec"lib": [ "ES2020.Promise" ],

Il semble que la réponse pour promise.allSettledn'inclut pas resultou reason.

Lors de l'exécution de la construction de typescript, j'obtiens l'erreur suivante:

Property 'reason' does not exist on type 'PromiseSettledResult<IMyPromiseResult>'.

et

Property 'value' does not exist on type 'PromiseRejectedResult'.

Mon bloc de code ressemble à ceci et comme vous pouvez le voir, j'essaie d'accéder reasonet de resultpartir de toutes les promesses qui sont résolues.

const myPromise = async () : Promise<IMyPromiseResult> {
  return new Promise((resolve) => {
    resolve("hello world")
  })
}

const data = await Promise.allSettled([
  myPromise()
]);

const response = data.find(res => res.status === 'fulfilled')?.result;

if(!response) {
  const error = data.find(res => res.status === 'rejected')?.reason;
  throw new Error(error);
}

Comment puis-je mettre à jour la déclaration Promise.allSettled pour inclure les interfaces appropriées?

Réponses

2 Jens Nov 20 2020 at 11:46

Comme Bergi l'a mentionné, TypeScript ne sait pas si le type est PromiseFulfilledResult/ PromiseRejectedResultlors de la vérification des types.

Le seul moyen est de présenter le résultat promis. Cela peut être fait parce que vous avez déjà vérifié que la promesse résolue est soit tenue, soit rejetée.

Voir cet exemple:

const myPromise = async (): Promise<string> => {
  return new Promise((resolve) => {
    resolve("hello world");
  });
};

const data = await Promise.allSettled([myPromise()]);

const response = (data.find(
  (res) => res.status === "fulfilled"
) as PromiseFulfilledResult<string> | undefined)?.value;

if (!response) {
  const error = (data.find(
    (res) => res.status === "rejected"
  ) as PromiseRejectedResult | undefined)?.reason;
  throw new Error(error);
}
2 bela53 Nov 20 2020 at 13:13

Définissez le findrappel comme type guard, qui renvoie un prédicat de type:

type IMyPromiseResult = string

const response = data.find(
  (res): res is PromiseFulfilledResult<string> => res.status === 'fulfilled'
)?.value;

if (!response) {
  const error = data.find(
    (res): res is PromiseRejectedResult => res.status === 'rejected'
  )?.reason;
  throw new Error(error);
}

Terrain de jeu de démonstration