TypeScript: New errors with RxJS on 2.4.1

When using the TS 2.4.1 and RxJS 5.4.1 (latest), I get a new error that I didn’t have before upgrading to using TS 2.4.1.

You may already be aware of this—it is an insiders build after all—but thought I should point it out just in case.

❯ yarn list typescript
└─ typescript@2.4.1-insiders.20170615

❯ yarn list rxjs
└─ rxjs@5.4.1

❯ tsc
node_modules/rxjs/Subject.d.ts(16,22): error TS2415: Class 'Subject<T>' incorrectly extends base class 'Observable<T>'.
  Types of property 'lift' are incompatible.
    Type '<R>(operator: Operator<T, R>) => Observable<T>' is not assignable to type '<R>(operator: Operator<T, R>) => Observable<R>'.
      Type 'Observable<T>' is not assignable to type 'Observable<R>'.
        Type 'T' is not assignable to type 'R'.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 3
  • Comments: 35 (13 by maintainers)

Commits related to this issue

Most upvoted comments

Why not use an augmentation to resolve this temporarily without downgrading TypeScript or upgrading RxJS to an unstable version? The following works with TypeScript@2.4.1

// augmentations.ts
// TODO: Remove this when RxJS releases a stable version with a correct declaration of `Subject`.
import {Operator} from 'rxjs/Operator';
import {Observable} from 'rxjs/Observable';

declare module 'rxjs/Subject' {
  interface Subject<T> {
    lift<R>(operator: Operator<T, R>): Observable<R>;
  }
}

@DanielRosenwasser @OliverJAsh FYI: This was resolved with the release of rxjs 5.4.2, and this issue can be closed.

All: rxjs 5.4.2 resolves this issue.

Either way, this issue can be closed as it was a bug in rxjs, not TypeScript.

@AneelaBrister Typescript version 2.3.4 seems to continue to work.

fyi the fix already landed on RxJS 5.4.2 (changelog), you can either close this issue or leave it open.

Bumping RxjS to v5.4.2 fixed it in both TypeScript and Angular in my case, and I no longer need this noStrictGenericChecks workaround & can safely take it out from tsconfig.json too.

@OliverJAsh incorrect … if you had read my post correctly … I referenced 2.4.0 … not 2.4.1 - make sure your package.json file references 2.4.0 exactly - not ^2.4.0 or ~2.4.0 which will upgrade you to 2.4.1

… I don’t know why i bother really.

it also makes the title of this ticket incorrect as TypeScript 2.4.0 works with rxjs 5.4.1 - however TypeScript 2.4.1 does not work with rxjs 5.4.1.

If you want to use TypeScript 2.4.1 - then you will need to upgrade to rxjs 6 alpha … I really hope you’re not using that in production . 😕

@DanielRosenwasser The problem is that they’ve been trying to use Subjects in a way that is fundamentally type-unsafe. I don’t know if anything’s changed in the year since that discussion happened, but in terms of the actual JS they want a Subject<T>, when transformed by an operator that takes Ts and produces Rs, to still produce a Subject (one that forwards all its values to this), instead of an Observable<R>. The reason they want to do this has something to do with two way communication in the websocket subject implementation.

None of this makes sense from the type system perspective, because it only makes sense to define lift for Observables. It just so happens that a Subject<T> is also an Observable<T>, but its implementation of lift<R> should be no different. The only sensible fix (and one which mirrors how the types are defined in Java/.NET) is to just delete this method and revisit what is going on in the websocket code. There’s more details in the issue I linked, but the way they are using subjects can mask runtime bugs.

Alternatively, that entire method should be typed any-ly, because there is no sensible way to express in types what they are doing.

Hey all, you can get around this using the --noStrictGenericChecks flag. Sorry for the inconvenience.

using typescript 2.3.4 or rxjs 6 alpha npm install rxjs@6.0.0-alpha.0

As others have already pointed out, at least until this issue is fully resolved, being precise about which version of TypeScript and RxJS you specify is crucial for working around this issue, especially for Angular-CLI apps.

The relevant entries in my package.json are shown below. Notice the absence of any ~ or ^ characters in the version number:

    "dependencies": {
 
       "rxjs": "5.4.1"

    }

    "devDependencies" : {

        "typescript": "2.4.0"

    }

My app was generated using Angular-CLI 1.1.3

I uninstalled typescript 2.4.1 and installed 2.3.4, it was resolved.

Using typescript 2.3.4 worked. rxjs 6 alpha gave an unmet peer dependency with angular/router

@floodedcodeboy I just tested typescript 2.4.1 and rxjs 5.4.1, to no avail:

❯ npm list typescript
├── typescript@2.4.1

❯ npm list rxjs
├── rxjs@5.4.1

❯ tsc
node_modules/rxjs/Subject.d.ts(16,22): error TS2415: Class 'Subject<T>' incorrectly extends base class 'Observable<T>'.
  Types of property 'lift' are incompatible.
    Type '<R>(operator: Operator<T, R>) => Observable<T>' is not assignable to type '<R>(operator: Operator<T, R>) => Observable<R>'.
      Type 'Observable<T>' is not assignable to type 'Observable<R>'.
        Type 'T' is not assignable to type 'R'.

Sounds like the only solution is to upgrade to rxjs 6 alpha.

I’ve used typescript 2.4.0 with rxjs 5.4.1 and that works fine.

rxjs 6.0.0-alpha.0 still won’t fix it for me, I’m still getting:

ERROR in [at-loader] ./node_modules/rxjs/Subject.d.ts:16:22
    TS2415: Class 'Subject<T>' incorrectly extends base class 'Observable<T>'.
  Types of property 'lift' are incompatible.
    Type '<R>(operator: Operator<T, R>) => Observable<T>' is not assignable to type '<R>(operator: Operator<T, R>) => Observable<R>'.
      Type 'Observable<T>' is not assignable to type 'Observable<R>'.
        Type 'T' is not assignable to type 'R'.

edit: may be a result of unmet peer dependencies?

Unmet peer dependency errors in this instance just means that those angular dependencies require RxJS 5.0.1 or higher, but below 6. Angular could still work with RxJS higher than they have specified, as they often work with higher versions of TypeScript. But I think you’re always at risk of some part of Angular not working or an arbitrary patch or minor version update breaking your build.

So use the solution proposed by @aluanhaddad instead, unless you for some other reason want to use the next version of RxJS already.

@floodedcodeboy You’re correct. 2.4.0 works but 2.4.1 does not. I will update the issue title.

Confusingly, the releases page lists 2.4.1 as “2.4”:

image

@claudiuconstantin If another dependency directly depends on it, i.e. not just a peer dependency, you have RxJS in your project the same way you have it if you depended on it directly. So the augmentation should work just as well.

Replaced typescript from ^2.4.1 to 2.4.0 worked for me

Confusingly, the releases page lists 2.4.1 as “2.4”

It isn’t confusingly in as much as every minor release of TypeScript has followed that pattern for an extended period of time. Because of some internal challenges, from what I understand, #.#.0 will never be the final release of a version of TypeScript. The first patch public release will always be #.#.1 and tagged appropriately in npm.

@OliverJAsh There was a long debate about this in reactivex/rxjs#1234. It’s always seemed to me like the bug is in rxjs, in that that override in Subject shouldn’t be there in the first place.