Избегайте жалоб Typescript на неназначенное значение, которое никогда не будет присвоено - PullRequest
0 голосов
/ 03 апреля 2020

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

Полная функция выглядит следующим образом:

export function select<T>(inStream: Observable<T>): T {
  let value: T;

  race(
    inStream,
    throwError(
      new Error(
        select.name + " expects a synchronous stream. Received an asynchronous stream."
        )
      )
    )
    .pipe(take(1))
    .subscribe(val => {
      value = val;
    });

  return value;  
}

Она работает как положено и выдает ошибка, если inStream не является синхронным, что означает, что я либо всегда получаю значение в последнем / текущем излучении, ИЛИ ошибку.

Однако машинописный текст жалуется на то, что значение используется до того, как оно будет присвоено. Я мог понять, что Typescript недостаточно умен, чтобы понять, как я запускаю синхронность или ошибку, и тестирование показывает, что значение всегда будет установлено правильно, когда поток на самом деле является синхронным, иначе мы получим ошибку.

Так как же мне избежать этого глупого дурацкого Typescript? Я не очень склонен игнорировать это, хотя я обдумываю это, если ни у кого нет хороших предложений.

В любом случае спасибо!

(Демонстрация для демонстрации работоспособности как ожидается, что мы можем сосредоточиться на решении машинописного текста, а не отвлекаться на то, что я делаю с кодом:

https://stackblitz.com/edit/rxjs-select-demo?file=index.ts

select используется дважды в этот пример. Сначала в потоке syn c и получает значение. Второй раз в потоке asyn c и выдает ошибку и не возвращает никакого значения. Perfect.)

1 Ответ

0 голосов
/ 03 апреля 2020

Поскольку subscribe часто ожидается , который будет использоваться асинхронно, я думаю, что самым чистым решением было бы преобразовать его в Обещание и вернуть это Обещание:

export function select<T>(inStream: Observable<T>): Promise<T> {
    return race(
        inStream,
        throwError(
            new Error(
                select.name + " expects a synchronous stream. Received an asynchronous stream."
            )
        )
    )
        .pipe(take(1))
        .toPromise();
}

Конечно вам также необходимо вызвать .then или await Обещание для потребителя select.

Вы также можете вернуть наблюдаемое и использовать вместо него его методы, если это больше подходит для вашего использования. case.

Это также делает код более расширяемым, если / когда вам необходимо настроить его для работы с асинхронными потоками.

...