Typescript: Need something more robust than polymorphic `this` typing for RxJS

Created on 1 Dec 2015  路  6Comments  路  Source: microsoft/TypeScript

I was pretty excited about this typing for RxJS, since it does have a sort of "fluent" style interface. However we have some issues with it that are discussed here: https://github.com/ReactiveX/RxJS/issues/846

Basically, we have operators that return same-shaped, but different generic types:

map for example: Observable<T>.prototype.map<R>((value: T) => R): Observable<R>

The reason we were looking at this typing the above is that map doesn't always return an Observable, it could be called on a Subject which is a subclass of Observable. In that case, it actually returns a Subject, not an Observable, because of our fancy lift mechanism:

The Observable's lift:
https://github.com/ReactiveX/RxJS/blob/2896556afe8b663d4f983da1830fe407841e7d5b/src/Observable.ts#L51-L63

The Subject's lift:
https://github.com/ReactiveX/RxJS/blob/2896556afe8b663d4f983da1830fe407841e7d5b/src/Subject.ts#L37-L41

How lift is used (in map for example):
https://github.com/ReactiveX/RxJS/blob/2896556afe8b663d4f983da1830fe407841e7d5b/src/operators/map.ts#L17

It would be fantastic if we could provide our TypeScript users with the proper type information in their IDEs. Perhaps some additional syntax like this<R> would fit the bill? It's also worth noting that operators always return a new instance, rather than the same this instance, if that makes a difference.

Discussion Duplicate Needs Proposal

All 6 comments

I think this is another instance of the higher order generic referenced in: https://github.com/Microsoft/TypeScript/issues/1213 combined with this types. i think you want to say something like:

map<T<*> extends Observable<*>, R, U>(this: T<U>, fn: (value: U) => R): T<R>

@mhegazy that looks something like it yeah. My C# is rusty, but I think in C# it was something like map<T, R, U>(this: T<U>, fn: (value: U) => R) where T<U> : Observable<U> or the like.

I'm pretty sure C# doesn't support higher-kinded types either, so it'll fail at T<U>.

No - C# does not yet have higher-kinded types.

@weswigham bummer. Not that I think it would be too useful in C# in most cases. But since TypeScript has JavaScript as a build target, I think it would be useful here. Well, clearly, because we've hit the need.

@mhegazy, @blesh

for your example you do not need higher kinded types, f-bounded polymorphism is sufficient
your example can be expressed in C# as
static T map<T, R, U>(this T @this, Func<U, R> fn) where T : Observable<U> { ... }
which is an extension method

and in typescript (since 1.8 I think) as
map<T extends Observable<U>, R, U>(that: T, fn: (value: U) => R): T { ... }
which is unfortunately an ordinary function

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rbuckton picture rbuckton  路  139Comments

tenry92 picture tenry92  路  146Comments

rwyborn picture rwyborn  路  210Comments

yortus picture yortus  路  157Comments

jonathandturner picture jonathandturner  路  147Comments