microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
101.12k stars 12.5k forks source link

Unable to mark JS functions as not being constructors (TS80002) #43812

Open Paril opened 3 years ago

Paril commented 3 years ago

Bug Report

TS80002 ("This constructor function may be turned to a class declaration") is a useful tool, but, it often breaks syntax coloring and classification of functions for things like out-of-line event handlers. There seems to be no way to mark a function as "not a constructor" (would the @function JSDoc hint maybe serve this purpose?)

šŸ”Ž Search Terms

jsdoc typescript constructor ts80002

šŸ•— Version & Regression Information

āÆ Playground Link

Playground link with relevant code

šŸ’» Code

/**
 * @this {HTMLElement}
 * @param {MouseEvent} e
 */
function test(e)
{
    this.textContent = '500';
}

document.addEventListener('click', test);

šŸ™ Actual behavior

TypeScript marks the function test as a constructor for a type. As a consequence, too, VSCode marks it as a type, and not a function, which is confusing for navigation purposes.

šŸ™‚ Expected behavior

TypeScript should be able to detect that with a @this hint (or @function perhaps?) that this isn't a constructor.

Ginden commented 2 years ago

There seems to be no way to mark a function as "not a constructor"

There is way to mark function as not a constructor.

Eg.

function foo(this: void) {}
function bar(this: HTMLElement) {}

It seems like JSDoc integration doesn't pick it.

boneskull commented 2 years ago

I'm hitting this as well. I ended up refactoring my code. But I figured out a workaround:

/**
 * @this {HTMLElement}
 * @param {MouseEvent} e
 */
function test(e) {
  const instance = /** @type {HTMLElement} */(this);
  instance.textContent = '500';
}
document.addEventListener('click', test);

I don't think the current behavior is necessarily wrong, and is probably the Right Thing most of the time. Though it looks like the @this tag in the function docstring is ignored; perhaps that is the problem.

nightwing commented 11 months ago

The situation have somewhat improved in version 5 and declaring the value of event listener with @type works in some cases, but the function is still shown as class in hover tooltip. Playground Link

I believe the current behavior is quite wrong, and setting @this or @type should turn off the class detection heuristic.