функция `race`, вызывающая исключение Typescript, даже если она отлично работает - PullRequest
0 голосов
/ 24 июня 2018

У меня есть 2 наблюдаемые.Первый излучает numbers, второй - strings.

Эти 2 наблюдаемые начинают излучаться, когда излучают некоторые триггеры.Триггеры - это субъекты, и у каждого из 2 наблюдаемых есть свой собственный триггер.

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

Это код

const observableOfNumber = interval(100).pipe(take(10));
const observableOfNumberFunction = () => observableOfNumber;

const observableOfString = interval(100).pipe(map(number => String.fromCharCode(65 + number)), take(10));
const observableOfStringFunction = ()  => observableOfString;

const startEmittingNumbers = new Subject<any>()
const emittingNumbers = startEmittingNumbers
                        .pipe(
                            map(() => observableOfNumberFunction),
                        );

const startEmittingChars = new Subject<any>()
const emittingChars = startEmittingChars
                        .pipe(
                            map(() => observableOfStringFunction),
                        );


race(emittingNumbers, emittingChars)
.pipe(
    mergeMap(handler => handler())
)
.subscribe(console.log);

Этот код заставляет Typescript жаловаться на следующую ошибку

enter image description here

Код, похоже, работает нормально по своей сути.

Если я просто явно объявляю тип возвращаемого значения observableOfStringFunction как Observable<any>, то есть

const observableOfStringFunction = (): Observable<any>  => observableOfString;

Typescript перестает жаловаться, и все работает отлично.

Аналогично, есливместо использования race я использую merge, Typescript не жалуется, даже если с точки зрения проверки типов merge и race должны вести себя одинаково.

Может кто-нибудь указать мнек причине этого другого поведения?

1 Ответ

0 голосов
/ 24 июня 2018

Это происходит потому, что тип , который возвращает race, совпадает с типом , который сначала выдает свои параметры (т. Е. Победитель гонки).- Observable<T>.

В вашем примере победитель гонки имеет тип number, потому что Type Checker, вероятно (возможно) также оценивает тип первых аргументов как тип возвращаемого значения, а затем ожидает каждого последующегоэмиссия должна быть того же типа (что это не так).Если бы вы изменили свои аргументы, вы заметили бы, что IntelliSense выдаст вам ту же ошибку для вашего emittingNumbers параметра.Вот почему IDE жалуется, но код все еще выполняется.

Вот более явный пример:

const obs1 = interval(1000).pipe(mapTo('fast one')); // Emits first, type string
const obs2 = interval(3000).pipe(mapTo(1)); // Type number, TypeScript will complain
const obs3 = interval(5000).pipe(mapTo('slow one'));

race(obs3, obs1, obs2)
.subscribe(
  winner => console.log(winner)
);

const {
  Observable, 
  interval,
  Subject,
  race
} = rxjs;
const { 
  map, 
  take, 
  mergeMap,
  mapTo 
} = rxjs.operators;

const obs1 = interval(1000).pipe(mapTo('fast one'));
const obs2 = interval(3000).pipe(mapTo(1)); // TypeScript will complain about this
const obs3 = interval(5000).pipe(mapTo('slow one'));

race(obs3, obs1, obs2)
.subscribe(
  winner => console.log(winner)
);
<script src="https://unpkg.com/rxjs/bundles/rxjs.umd.min.js"></script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...