Преобразуйте массив обещаний в одно обещание, которое может быть одним из включенных типов: [P <string>, P <number>] -> Promise - PullRequest
3 голосов
/ 06 августа 2020

Я пытаюсь создать функцию, которая будет возвращать первое установленное значение из массива обещаний

const firstSettledValue = (...promises: Array<Promise<any>>): Promise<any> {
   // ...
}

const v = firstSettledValue(
  new Promise<string>(),
  new Promise<number>(),
  new Promise<boolean>()
)

v // Promise<string | number | boolean>

Ответы [ 2 ]

1 голос
/ 06 августа 2020

Вы можете просто использовать Promise.race():

const v = Promise.race([
  new Promise<string>(() => {}),
  new Promise<number>(() => {}),
  new Promise<boolean>(() => {})
]);

v // Promise<string | number | boolean>

Тип возвращаемого значения определен правильно.

0 голосов
/ 06 августа 2020

Используйте, мы можем использовать Generi c Rest Parameters TypeScript, чтобы точно справиться с этим.

Это позволяет объявлять общий тип c кортежа, который фиксирует индивидуальный тип каждый аргумент при вызове функции.

Давайте разберем его.

Сначала мы зафиксируем тип каждого аргумента, переданного функции

const firstSettledValue = <P extends Promise<any>[]>(...promises: P) => {}

const v = firstSettledValue(
  Promise.resolve('Hello World'),
  Promise.resolve(15),
  Promise.resolve(false)
)

Теперь, мы можем получить тип объединения для всех всех аргументов, то есть элементов P, с помощью P[number].

type U = P[number] // string | number | boolean

Обратите внимание, что в приведенном выше P[0] это тип string, P[1] - это тип number и т. Д.

Однако мы не можем использовать P[Number] непосредственно в приведенном выше коде, потому что наши элементы являются обещаниями, и нам нужно извлечь их значение типов.

Для этого мы можем ввести небольшой вспомогательный тип

type ValueType<T> = T extends Promise<infer U>
  ? U
  : T;

Учитывая Promise<T>, приведенный выше помощник производит T.

Наконец, мы составьте эти техники вместе

const firstSettledValue = <P extends Promise<any>[]>(...promises: P): Promise<ValueType<P[number]>> => {
  const randomIndex = Math.floor(Math.random() * 100) % promises.length;
  return promises[randomIndex];
};

const v = firstSettledValue(
  Promise.resolve('Hello World'),
  Promise.resolve(15),
  Promise.resolve(false)
);

type ValueType<T> = T extends Promise<infer U>
  ? U
  : T;

Playground Link

И мы сделали. v имеет тип Promise<string | number | boolean> на основе обещаний, указанных в вызове.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...