TypeScript: Unexpected deprecation warning after upgrading to TypeScript v4.2.2

Bug Report

🔎 Search Terms

RxJS Deprecation Warning TSLint ESLint VSCode Signature Doc Tags DocTags

🕗 Version & Regression Information

Since TypeScript v4.2.2, I get deprecation warnings with RxJS, that I was not getting in TypeScript v4.1.5

I first opened an issue on RxJS (here), but it may be a TypeScript issue

💻 Code

import { Observable, Subject } from 'rxjs';

const somethingHappened: Subject<void> = new Subject();
const somethingHappened$: Observable<void> = somethingHappened.asObservable();

// Deprecation warning on the next line
somethingHappened$.subscribe(() => {
  console.log('something happened');
});

somethingHappened.next();

🙁 Actual behavior

When I subscribe to the observable, I get the deprecation warning subscribe is deprecated: Use an observer instead of a complete callback even though I’m not using any complete callback

It occurs with both TSLint v6.1.3 and ESLint v7.21.0 (using eslint-plugin-deprecation v1.2.0)

Here are the signatures for the subscribe method in RxJS v6.6.6 :

subscribe(observer?: PartialObserver<T>): Subscription;
/** @deprecated Use an observer instead of a complete callback */
subscribe(next: null | undefined, error: null | undefined, complete: () => void): Subscription;
/** @deprecated Use an observer instead of an error callback */
subscribe(next: null | undefined, error: (error: any) => void, complete?: () => void): Subscription;
/** @deprecated Use an observer instead of a complete callback */
subscribe(next: (value: T) => void, error: null | undefined, complete: () => void): Subscription;
subscribe(next?: (value: T) => void, error?: (error: any) => void, complete?: () => void): Subscription;

If I understand this correctly, in my case it should be using this signature :

subscribe(next?: (value: T) => void, error?: (error: any) => void, complete?: () => void): Subscription;

Which is not deprecated

🙂 Expected behavior

There should be no deprecation warning

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 59
  • Comments: 45 (5 by maintainers)

Commits related to this issue

Most upvoted comments

If you really need TypeScript 4.2 -> Wait for a patch

If you don’t need TypeScript 4.2 -> You can simply downgrade your project and VSCode to use TypeScript 4.1

  • Open a TypeScript file
  • Click on the current version of TypeScript you are using (bottom right corner of VSCode)
  • Choose “Select TypeScript Version…”
  • Choose “Use Workspace Version”

I am still getting this issue. Typescript 4.2.3, VScode 1.54.3 running on macOS Catalina. It also started happening after updating to VScode 1.54.1

Re-opening until a 4.2 patch release, and brought up the request for a patch again 👍🏻

Same here, problem not solved yet (waiting for 4.3.X release).

VS Code now ships with TypeScript 4.2.2. This major update includes many TypeScript language improvements, along with many improvements and bug fixes for JavaScript and TypeScript tooling.

FYI: The issue is still present with TypeScript 4.2.3

Looks like VSCode gives us all the @deprecated annotations, even though Ctrl + Clicking the method takes us to the correct signature :

image

I have found this issue after upgrade vscode.

Using this https://github.com/microsoft/TypeScript/issues/43053#issuecomment-809677495 to force VScode to use TypeScript v4.2.4 instead of v4.2.3 I can confirm the issue has been fixed.

Unfortunately the branch for VSCode v1.55 still hasn’t been updated with TypeScript v4.2.4. I opened a request on the VSCode repository https://github.com/microsoft/vscode/issues/121583 to get this fixed in VSCode 1.55.3 hopefully.

EDIT: Well, looks like we’ll have to wait for VSCode v1.56 (scheduled for may), if we want to use the default TypeScript version of VSCode ^^

Updated today to version 1.55 of VS code. The issue still persists.

Same here, problem not solved yet (waiting for 4.3.X release).

so why this issue is closed?

have this issue solved?

Actually, it never disappeared ^^

The fix has not been merged for the 4.2.X branch yet, it has only been merged for the next 4.3.X release.

You can track the merge progress for the 4.2.X branch here : https://github.com/microsoft/TypeScript/pull/43180

Same issue here: no matter if I use .subscribe((value) => { /* code */ }); or .subscribe({next: (value) => { /* code */ }}):

looking forward for a fix. thank

You can also use the nightly version of the TS extension: https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-typescript-next

I think we should open a issue on Eslint since tslint is now deprecated

Hi folks, I’m not 100% that this is a TypeScript issue but an issue in both tslint and eslint which maybe aren’t checking whether the used version of a function is deprecated.

When you make a blank project with:

mkdir 43053
yarn init -y
yarn add typescript rxjs
touch index.ts
code . 

Then open the file:

Screen Shot 2021-03-09 at 3 09 34 PM

We don’t report to vscode that the former example is deprecated, which is what would happen if TypeScript thought it was deprecated.

That said, there’s a reasonable possibility that the underlaying deprecations API usage which tslint and eslint may be using could have changed in 4.2 though which might have caused this, which I’ll be looking into next

Thank you for opening this issue - I have a huge Angular project with endless tslint deprecation warnings 🚀

My 2 cents, I’m not sure this is the right place to post this, but a deprecation warning still occurs on a specific situation. Actually, it’s in the ‘body-parser’ types of the Express plugin

/** @deprecated */
declare function bodyParser(
    options?: bodyParser.OptionsJson & bodyParser.OptionsText & bodyParser.OptionsUrlencoded,
): NextHandleFunction;

declare namespace bodyParser {
    //...
    /**
     * Returns middleware that only parses json and only looks at requests
     * where the Content-Type header matches the type option.
     */
    function json(options?: OptionsJson): NextHandleFunction;
    //...
}

Using bodyParser.json()in VSCode display the bodyParserpart as stroked (deprecated), and the json() part as it should (unstroked)… The deprecation feature, in this case, doesn’t understand that thebodyParserrefer to the namespace and not the function…

TypeScript 4.2.4 has now been released, so we can close this.

A VSCode update should follow in about a week.

Same issue here I have tried everything no chance.

Today’s update to VSCode sees it running Typescript 4.2.4 and the deprecation warning got Subscribe is no longer present!

OK, this looks like is an un-expected side-effect of https://github.com/microsoft/TypeScript/pull/42098

Repro’d without the whole rxjs pipeline:

interface PartialObserver<T> {}
interface Subscription {}
interface Unsubscribable {}

export interface Subscribable<T> {
  subscribe(observer?: PartialObserver<T>): Unsubscribable;
  /** @deprecated 1 Use an observer instead of a complete callback */
  subscribe(next: null | undefined, error: null | undefined, complete: () => void): Unsubscribable;
  /** @deprecated 2 Use an observer instead of an error callback */
  subscribe(next: null | undefined, error: (error: any) => void, complete?: () => void): Unsubscribable;
  /** @deprecated 3 Use an observer instead of a complete callback */
  subscribe(next: (value: T) => void, error: null | undefined, complete: () => void): Unsubscribable;
  subscribe(next?: (value: T) => void, error?: (error: any) => void, complete?: () => void): Unsubscribable;
}

interface ThingWithDeprecations<T> extends Subscribable<T> {
    subscribe(observer?: PartialObserver<T>): Subscription;
    /** @deprecated Use an observer instead of a complete callback */
    subscribe(next: null | undefined, error: null | undefined, complete: () => void): Subscription;
    /** @deprecated Use an observer instead of an error callback */
    subscribe(next: null | undefined, error: (error: any) => void, complete?: () => void): Subscription;
    /** @deprecated Use an observer instead of a complete callback */
    subscribe(next: (value: T) => void, error: null | undefined, complete: () => void): Subscription;
    subscribe(next?: (value: T) => void, error?: (error: any) => void, complete?: () => void): Subscription;
}

declare const a: ThingWithDeprecations<void>

// Fails with the above script
a.subscribe(() => {
  console.log('something happened');
});

The deprecations which are returned come from Subscribable not ThingWithDeprecations

So far, I’ve narrowed it down to being a change in the returned values from getJsDocTags and getResolvedSignature.

With this script:

import * as ts from "typescript";

// Loop through the AST to find call expressions:
function traverse(sourceFile: ts.SourceFile) {
  lookAtNode(sourceFile);

  function lookAtNode(node: ts.Node) {
    if (ts.isCallExpression(node)) {
      check(node)
    }

    ts.forEachChild(node, lookAtNode);
  }
}

// Setup TypeScript environment
let program = ts.createProgram(["index.ts"], {});
let checker = program.getTypeChecker();
const sourceFile = program.getSourceFile("index.ts")!
traverse(sourceFile);

// Look at call expressions to see if they're deprecated based on code in tslint and SonarJS
function check(callExpression: ts.CallExpression) {
  const tc = checker;
  console.log("\n\nLooking at: ", callExpression.getText())

  const signature = tc.getResolvedSignature(callExpression);
  if (signature) {
    const tags = signature.getJsDocTags()
    const deprecated = tags.find(t => t.name === "deprecated")

    if (deprecated) {
      console.log("Deprecation from `getJsDocTags`", deprecated)
    }
  }
}

In 4.1:

Looking at:  somethingHappened.asObservable()


Looking at:  somethingHappened$.subscribe(() => {
  console.log('something happened');
})


Looking at:  console.log('something happened')


Looking at:  somethingHappened$.subscribe(null, undefined, () => {})
Deprecation from `getJsDocTags` {
  name: 'deprecated',
  text: 'Use an observer instead of a complete callback'
}

In 4.2:


Looking at:  somethingHappened.asObservable()


Looking at:  somethingHappened$.subscribe(() => {
  console.log('something happened');
})
Deprecation from `getJsDocTags` {
  name: 'deprecated',
  text: 'Use an observer instead of a complete callback'
}


Looking at:  console.log('something happened')


Looking at:  somethingHappened$.subscribe(null, undefined, () => {})
Deprecation from `getJsDocTags` {
  name: 'deprecated',
  text: 'Use an observer instead of a complete callback'
}


Looking at:  somethingHappened.next()

It’s unlikely this output is what we want, so hold off on new issues for other projects.

Thank god I thought I need to update the subscriptions to a new syntax …