Jak korzystać z promise.allSettled with maszynopis?

Nov 20 2020

Promise.allSetttledKompilacja maszynopisu kończy się niepowodzeniem, ponieważ nie wygląda na to, mimo że ustawiłem kompilator konfiguracji ts z opcjami"lib": [ "ES2020.Promise" ],

Wygląda na to, że odpowiedź na promise.allSettlednie zawiera resultlub reason.

Podczas budowania skryptu pojawia się następujący błąd:

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

i

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

Mój blok kodu wygląda tak i jak widać, próbuję uzyskać dostęp reasoni resultod eaech do obietnic, które zostaną rozwiązane.

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);
}

Jak mogę zaktualizować deklarację Promise.allSettled, aby zawierała prawidłowe interfejsy?

Odpowiedzi

2 Jens Nov 20 2020 at 11:46

Jak wspomniał Bergi, TypeScript nie wie, czy typ jest PromiseFulfilledResult/ PromiseRejectedResultpodczas sprawdzania typów.

Jedynym sposobem jest oddanie obiecującego wyniku. Można to zrobić, ponieważ już zweryfikowałeś, że rozwiązana obietnica jest spełniona lub odrzucona.

Zobacz ten przykład:

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

Zdefiniuj findcallback jako typ strażnika, który zwraca predykat typu:

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);
}

Demo Playground