microsoft / vscode-eslint

VSCode extension to integrate eslint into VSCode
MIT License
1.73k stars 335 forks source link

Typescript types out of date for generated file #1769

Closed alex-statsig closed 8 months ago

alex-statsig commented 8 months ago

I've had an issue for a while where the lint results shown from VSCode seem to use out-of-date types for generated types. This comes about in two ways:

  1. I generate graphql types using some codegen (I modify schema.graphql, which generates some types in __generated__/schema.graphql.ts)
  2. I modify source types in another package of a monorepo and rebuild, generating new types in /dist/index.d.ts (note that the dist folder is referenced rather than source to ensure separate compilations, with separate typescript settings potentially)

The result is that I get lint issues such as "Unsafe call of an any typed value." because the linter doesnt seem to know that something exists. When I run tsc or eslint directly via terminal, the issues are not present. This seems to indicate the extension (or eslint server) may be doing some special caching of the types which fails to re-evaluate files modified by codegen. The only easy way to fix this is by reloading the window or restarting the eslint server.

Note that the Typescript tooltips in vscode do correctly reflect the types, so I will see somethign like this: Screenshot 2024-01-19 at 10 19 14 AM (Notice that Typescript knows the function returns a "string", yet the eslint extension complains about an "any" type)

Interestingly if I have the generated file open in VSCode when I run the codegen (ex. I open __generated__/schema.graphql.ts then run codegen), it seems to correctly detect that the file changed and updates the linting shortly after.

dbaeumer commented 8 months ago

@alex-statsig this is something the TypeScript ESLint plugin needs to address and to my knowledge they have an issue for this. It is that plugin that caches the types. The Extension doesn't know anything about this.

alex-statsig commented 8 months ago

@alex-statsig this is something the TypeScript ESLint plugin needs to address and to my knowledge they have an issue for this. It is that plugin that caches the types. The Extension doesn't know anything about this.

I filed it here because I don't run into the issue when running lint in my terminal though, only through the plugin. Perhaps only the plugin is using caching, but then what caching mode is being used which causes the issue? (I know some of lint's cache modes are not guaranteed to give correct results)

dbaeumer commented 8 months ago

When you run eslint in the terminal it is a new process on every run. That it is why it works there. Fror performance reasons the extension runs a server which reuses eslint. Otherwise validate on typing would be slow. TypeScript in general supports such a server mode. So the eslint plugin could as well.

You can use tasks to execute eslint freshly for validation. But as said that has performance implications.

dbaeumer commented 8 months ago

The plugin maintainers pinged be here to see if there is something we can find out to make the work better: https://github.com/microsoft/vscode-eslint/issues/1774

alex-statsig commented 8 months ago

@dbaeumer The distinction here compared to https://github.com/microsoft/vscode-eslint/issues/1774 is that it only seems to apply to generated files.

For example: If I have file A.ts referencing a type from file B.ts both in the same local package, and I update the contents of file B.ts, I can return to file A.ts and see the relevant linting errors (Ex. @typescript-eslint/no-unsafe-call if I typo the name of a function, but not if it matches the name I just added).

However, when the change is codegen (two examples of this are a monorepo where the source .ts file generates built .d.ts files, or graphql code-gen type generation; the former being very common and painful), the changes are not reflected in A.ts until I restart eslint. This means any function calls will show up failing "@typescript-eslint/no-unsafe-call" regardless of if they dont exist or do exist.

It's possible I'm incorrect about the exact details of the trigger here (i.e. that its codegenned), but it definitely seems different from https://github.com/microsoft/vscode-eslint/issues/1774 because of the circumstances which it does / doesn't cause issues for me.

Note additionally that these issues do not happen with the typescript extension (it provides the correct autocomplete suggestions in both scenarios, implying our TS setup is valid), and do not happen with commandline eslint. The confusing part to me still is why the eslint extension does work if the file is directly imported, but does not work for our codegen imports and monorepo library imports.