rxjs: Observable.from(iterable) generates Typescript compiler error
RxJS version: 5.0.3
Code to reproduce:
function* generateDoubles(seed: number) {
let i = seed;
while (true) {
yield i;
i = 2 * i; // double it
}
}
const iterator = generateDoubles(3);
const result = Rx.Observable.from<number>(iterator).take(10);
result.subscribe((x: number) => console.log(x));
Expected behavior: Since this is the example given on reactivex.io It would be expected to compile in Typescript without an error.
Actual behavior:
error TS2345: Argument of type 'IterableIterator<number>' is not assignable to parameter of type 'ObservableInput<number>'.
Type 'IterableIterator<number>' is not assignable to type 'PromiseLike<number>'.
Property 'then' is missing in type 'IterableIterator<number>'.
Additional information:
This seems to be an issue with the definition of ObservableInput<T>
:
export interface Subscribable<T> {
subscribe(observerOrNext?: PartialObserver<T> | ((value: T) => void), error?: (error: any) => void, complete?: () => void): AnonymousSubscription;
}
export declare type SubscribableOrPromise<T> = Subscribable<T> | PromiseLike<T>;
export declare type ObservableInput<T> = SubscribableOrPromise<T> | ArrayLike<T>;
The iterable type is missing.
A fix might be to add:
export interface IterableLike<T> {
[Symbol.iterator](): Iterator<T> | IterableIterator<T>;
}
// and fix ObservableInput<T>
export declare type ObservableInput<T> = SubscribableOrPromise<T> | ArrayLike<T> | IterableLike<T>;
tsconfig.json
{
"compilerOptions": {
"target": "es2015",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"alwaysStrict": true,
"declaration": true,
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"outDir": "dist",
"lib": ["dom", "dom.iterable", "es2015", "es2015.iterable", "scripthost"]
},
"include": [
"src"
]
}
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 5
- Comments: 25 (11 by maintainers)
What’s the current status on this issue? It’s really a bummer having to cast back to
<any>
. Is there any interest in adding afromIterable()
operator? Is there any better way to resolve this now that we’re up to TypeScript 2.4? @david-driscoll @felixfbeckerNow that we have
Iterable<T>
used elsewhere in the code base, and the fact that TypeScript with iterables have been out for a while, I think we can addIterable<T>
toObservableInput<T>
and then this problem goes away.We can augment
interface
s, but it doesn’t appear there is any way to augment type unions. Which kind of makes sense with how augmentation works, it’s kind of crappy though.We had
Iterable<T>
in there, during the early days, but we removed it because of problems with users that don’t have it enabled at the compiler level. This was before the compiler could choose a custom combination of libs (which came with 2.0 iirc). See #1582 for the code that removed it.Now that we have
lib:[]
we might be able to bring it back.Risks involve:
es2015.iterable
Ts2.2 is bringing in downlevel support for generators to ES3, via https://github.com/Microsoft/TypeScript/pull/12346 . So once we get to TS 2.2 this seems like an appropriate change, until then I’m not really sure.
I’m wondering if we should just throw our hands up with
from
and passany
to it. The type checking here is pretty painful, and then we have to check at run time anyhow.