Skip to content
Please note that GitHub no longer supports Internet Explorer.

We recommend upgrading to the latest Microsoft Edge, Google Chrome, or Firefox.

Learn more
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nameless `@typedef` has implicit any error on the associated identifier #36375

Open
TimvdLippe opened this issue Jan 23, 2020 · 8 comments · May be fixed by #36454
Open

Nameless `@typedef` has implicit any error on the associated identifier #36375

TimvdLippe opened this issue Jan 23, 2020 · 8 comments · May be fixed by #36454

Comments

@TimvdLippe
Copy link

@TimvdLippe TimvdLippe commented Jan 23, 2020

TypeScript Version: 3.7.5

Search Terms: typedef, jsdoc, noImplicitAny

Code

/**
 * @typedef {!{data: number}}
 */
export let EventTargetEvent;

Expected behavior:
No error when compiling with noImplicitAny

Actual behavior:
Variable 'EventTargetEvent' implicitly has an 'any' type.
Playground Link: https://www.typescriptlang.org/play/?ssl=1&ssc=1&pln=2&pc=22#code/PQKhCgAIUgBAXAngBwKYBNUDNIG8CEu6AhvMQFyQB2ArgLYBGqATgL6tQjDioAeyAe2bxIAG1QiAogDdUVeABVizAOYSZc+AG4gA

Related Issues: Originally discussed with @sandersn in #19983 who requested a separate issue

@sandersn sandersn changed the title Update `noImplicitAny` to not error on `@typedef` jsdoc Nameless `@typedef` has implicit any error on the associated identifier Jan 23, 2020
@sandersn

This comment has been minimized.

Copy link
Member

@sandersn sandersn commented Jan 23, 2020

Currently the error is correct, since the value EventTargetEvent actually does have the type any. The best way to fix this is to decide what type it should have. If I remember correctly, though, Closure code often has initialisers on declarations such that the value has a different type than the type.

@TimvdLippe is there closure code of the form

/** @typedef {{ x: number }} */
export let T = class {
}

where the class does not have an x property? An even smaller example would be export let T = 1, but I don't think I've seen that.

@TimvdLippe

This comment has been minimized.

Copy link
Author

@TimvdLippe TimvdLippe commented Jan 23, 2020

All @typedef that we have, have no initializer. Trying to add an initializer results in the following error:

[JSC_TYPE_MISMATCH] assignment
found   : null
required: None
Components._LinkInfo = null;
@TimvdLippe

This comment has been minimized.

Copy link
Author

@TimvdLippe TimvdLippe commented Jan 26, 2020

I looked at the implementation of the compiler and it seems rather straightforward to fix this. E.g. it would check, during variable initialization, if the jsdoc has a typedef. If so, set the variable to unknown, as usages of a variable with a typedef is illegal (but you should still be able to refer to it in jsdoc).

Do you mind if I try to create a PR for this issue with the above semantics?

TimvdLippe added a commit to TimvdLippe/TypeScript that referenced this issue Jan 27, 2020
Typedefs have two forms: specify a name in the `@typedef` declaration or
use the name of the variable declaration it is attached to. Since
`@typedef` types should only live in the type space, any reference to a
variable that has a `@typedef` attached to is illegal. As such, assign
it the `never` type if the `@typedef` itself does not specify a name.

Fixes microsoft#36375
@TimvdLippe TimvdLippe linked a pull request that will close this issue Jan 27, 2020
@TimvdLippe

This comment has been minimized.

Copy link
Author

@TimvdLippe TimvdLippe commented Jan 27, 2020

WIP PR at #36454 which passes all tests.

@RyanCavanaugh

This comment has been minimized.

Copy link
Member

@RyanCavanaugh RyanCavanaugh commented Jan 27, 2020

@sandersn what's the desired behavior?

@sandersn

This comment has been minimized.

Copy link
Member

@sandersn sandersn commented Jan 27, 2020

  • I think #36454, which sets the type to never, is pretty good because it makes it hard to use.
  • You could make value-space usage completely illegal, but this is stricter than our other JS handling.
  • The current behaviour of any is not too bad either, just annoying in the case that noImplicitAny is on. It means that nameless typedefs will always have an implicit any error, with the only workaround being to add a name.

I don't think this bug is worth fixing, though, because the new code only benefits (1) closure code bases (2) with noImplicitAny: true. I don't believe there are many of these. I don't think that justifies the support cost of the new code.

@sandersn

This comment has been minimized.

Copy link
Member

@sandersn sandersn commented Jan 28, 2020

Looks like #28162 includes the error I suggested, plus a lot more, already.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.