Comments (5)
I think this is a limitation on Typescript rather than RxJS.
With TS 5.1 or before, you couldn't do the following:
const a = true;
// b is Array<number> | Array<string>
const b = a ? [1] : ['1'];
// TS 5.1
// Error: This expression is not callable.
b.filter(r => {});
This was fixed in TS 5.2 for Arrays in specific: https://devblogs.microsoft.com/typescript/announcing-typescript-5-2/#easier-method-usage-for-unions-of-arrays
The problem is that Typescript can't find compatible signatures when you have SomeType<A> | SomeType<B>
. The workaround with arrays before 5.2 was to manually define the array type as an Array of the union:
const a = true;
const b: Array<number | string> = a ? [1] : ['1'];
// TS 5.1
// Now this works
b.filter(r => {});
And so your workaround is to do the same for observable. In your stackblitz you can try:
const tmp: Observable<undefined | null> = (a ? of(undefined) : of(null));
tmp.pipe(...)
And this will work. This is why from(a ? [undefined] : [null])
works: It returns an Observable<undefined | null>
directly instead of a Observable<undefined> | Observable<null>
from rxjs.
I filed an issue upstream... because I agree it's confusing, but I'm not sure this is on us... microsoft/TypeScript#56741
We might have a pipe()
overload with zero arguments that we could get rid of to provide better errors?
from rxjs.
I was wondering about the same thing, having a:
matchThingie(xx, {
caseA: () => someObs,
caseB: () => someOtherObs
}); // returns Observable<T> | Observable<U> so can't pipe
I figured I'd try to reproduce it (ok for like 5 minutes but still), adding pieces of the class one at a time but not having much luck, seems like TS is fine with it:
export interface OpFn<T, R> { (source: Observable<T>): Observable<R>; }
declare class Observable<T> {
source: Observable<any> | undefined;
operator: OpFn<any, T> | undefined;
constructor(subscribe?: (this: Observable<T>, subscriber: unknown) => () => void);
pipe(): Observable<T>;
pipe<A>(op: OpFn<T, A>): Observable<A>;
pipe<A, B>(op1: OpFn<T, A>, op2: OpFn<A, B>): Observable<B>;
// all the other ones
}
declare const y: Observable<number> | Observable<string>;
y.pipe();
// sees all overloads, and somehow the one with no args always returns the first member of the union
// so if I swap number and string, pipe returns Observable<string> instead of Observable<number>
I'm not sure which part of the class makes TS think the other overloads can't be there
And as I see Ryan asked for a simpler reproduction, might not be that easy creating one 😅
from rxjs.
Actually went a bit further, seems to be the observer in the subscribe() that breaks it:
interface Unsubscribable { unsubscribe(): void; }
interface OperatorFunction<T, R> { (source: Observable<T>): Observable<R>; }
interface Observer<T> { next(value: T): void; }
declare class Observable<T> {
pipe(): Observable<T>;
pipe<A>(op: OperatorFunction<T, A>): Observable<A>;
subscribe(observer: Partial<Observer<T>>): Unsubscribable;
}
declare const y: Observable<number> | Observable<string>;
y.pipe(); // only sees the first overload
from rxjs.
Related Issues (20)
- '.now()' is not a function error is thrown when the value of DateTimestampProvider.delegate is not valid HOT 1
- TestScheduler expectObservable not respecting subscription marbles when using toEqual
- Incorrect @deprecated for fromEvent overloads HOT 2
- test issue
- test issue
- rxjs.dev very often inaccessible HOT 10
- export map means node always resolves CJS HOT 7
- RxJs ships generators instead of native async/await HOT 1
- bindCallback: resultSelector destructuring callback argument if it's array HOT 1
- `every` operator sending multiple values when re-entrant HOT 1
- [email protected] has peer deps?! Oops
- ObservableInput<T> should support Thennable<T>, not PromiseLike<T> HOT 1
- Delay, timer and possibly other operators have a maximum milliseconds value, even when date is passsed HOT 1
- lost stacktrace after promise is resolved HOT 1
- Teardown and error/complete messages are out of order HOT 2
- Issue with catchError HOT 1
- Synchronous emit to `switchMap` during the processing of previous emit prevents the first from unsubscribing HOT 4
- False positive in deprecation with mergMap HOT 1
- it's possible to return an array in catchError() HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rxjs.