Skip to content
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

VSCode should default to using the TypeScript version in the current project #172732

Closed
Zamiell opened this issue Jan 29, 2023 · 6 comments
Closed
Assignees
Labels
*as-designed Described behavior is as designed typescript Typescript support issues

Comments

@Zamiell
Copy link

Zamiell commented Jan 29, 2023

VSCode Default Behavior Should Change

According to the documentation here:

VS Code ships with a recent stable version of the TypeScript language service and uses this by default to provide IntelliSense in your workspace. The workspace version of TypeScript is independent of the version of TypeScript you use to compile your *.ts files. You can just use VS Code's built-in TypeScript version for IntelliSense without worry for most common cases, but sometimes you may need to change the version of TypeScript VS Code uses for IntelliSense.

This current behavior makes a lot of sense in the situation where VSCode has no knowledge of what specific version of TypeScript should be used - like if you happen to be editing some JavaScript file in a JavaScript project. (VSCode uses TypeScript for JavaScript files in order to provide good IntelliSense.)

This current behavior does not make a lot of sense in the situation where you use "File --> Open Folder" on a TypeScript project. In this specific situation, VSCode is smart enough to automatically and magically read your project's tsconfig.json, so it should go one step further and automatically use your project's specific installed TypeScript version. In order to do this, VSCode could make some basic assumptions, like that it is installed in the node_modules folder, and so on.

TLDR - I am proposing that VSCode first and foremost attempts to use the project's currently-installed version of TypeScript automatically and by default. If it fails to do this for any reason, then it should revert to the existing behavior, which is to use the "official stable version" that is bundled with VSCode itself.

(Currently, it is of course possible to manually trigger VSCode to use the project's version of TypeScript by clicking on the "4.9.4" button in the bottom-right-hand corner of the screen. But this must be done manually by every person on the team working on a project and there is no way to force it to apply at a project-level.)


Motivation

The existing default behavior creates some really miserable situations.

My User Story

Back when TypeScript 4.9 just came out, I immediately updated the version of TypeScript in my project's repository and started using the satisfies operator. However, even after changing my "package.json" file and even after reinstalling my dependencies and even after restarting VSCode completely, I was still getting red squiggly lines in my editor saying that the satisfies operator did not exist. This led to a very frustrating troubleshooting experience.

Eventually, I discovered that the root of the problem was that VSCode was very slow to update the version of TypeScript that came bundled with the editor itself. And that by default, VSCode was using its own bundled version of TypeScript instead of the one specified in my "package.json" file. After manually clicking the "4.9.4" icon in the bottom of the screen and changing the version, everything worked fine.

That is, everything worked fine until other people on the team pulled down my changes and experienced the exact same problem. Now, we were experiencing this problem at scale - every person on the team had to manually change the option as well.

I Was Lucky

In the case of my story, the problem was around the brand-new satisfies operator, which tipped us off to the root of the problem being some kind of TypeScript version mismatch somewhere. However, we should note that this was actually a lucky case. Often times, TypeScript compiler errors will be due to a version mismatch, but nothing in the error itself will be related to a "new TypeScript thing".

(For example, consider the new enum narrowing behavior introduced in recent versions that changes the type signature of an O(1) reverse enum lookup.)

This leads to a frustrating troubleshooting experience, where you might go down the rabbit hole of assuming that a compiler error is due to some recent change in the code-base, until you eventually find that compiling passes in CI for some reason.


settings.json Considerations

VSCode should change the default behavior for the reasons outlined above. In the interim time period, we can get to work on creating hacky workarounds for our individual projects. However, as a secondary problem, there doesn't seem to be a way to do that either!

Historically, these kinds of VSCode issues could be solved on an individual project level by making sure that the "correct" option is commited to git in the project's ".vscode/settings.json" file. That way, they will be automatically inherited by anyone cloning the repository.

Unfortunately, there is not a way to specify this specific behavior via a VSCode setting. The closest thing we have is:

typescript.tsdk

According to the docs:

The typescript.tsdk workspace setting only tells VS Code that a workspace version of TypeScript exists. To actually start using the workspace version for IntelliSense, you must run the TypeScript: Select TypeScript Version command and select the workspace version.

So this does not actually solve the problem. Essentially, specifying the option at a project-level does nothing, because AFAIK by default VSCode will usually "pick up" your currently installed version of TypeScript anyway, at least if it is in a standard place like node_modules. (Caveat: I am not 100% sure of the specifics on how this setting actually works.)

typescript.enablePromptUseWorkspaceTsdk

We can enable a prompt for the people on our project's team, but they might accidently close the prompt. What we really want is to specify the behavior itself, not cause an annoying prompt.


Workspace Trust

For a potentially related issue, see #135713.

If there is some issue with workspace trust preventing a change of the default behavior that this issue recommends, then VSCode can be programmed to only look for project-installed versions of TypeScript when the project is trusted. Virtually everyone trusts their TypeScript projects anyway in order to run e.g. ESLint and Prettier and Jest, so this concession leaves very few people behind.

@Zamiell
Copy link
Author

Zamiell commented Jan 29, 2023

Some discussion from the TypeScript Discord:

mkantor — Today at 2:13 PM
one wrinkle i can see is that the user might open a typescript file in the project before they run npm install

Zamiel — Today at 2:17 PM
I don't think that's a particularly relevant wrinkle.
I proposed: "If it fails to do this for any reason, then it should revert to the existing behavior, which is to use the "official stable version" that is bundled with VSCode itself."
Thus, in the case you bring up, the flow would be that:

  1. It would see that TypeScript is installed in the package.json file.
  2. It would attempt to find TypeScript in the node_modules folder.
  3. It would fail to find it, because it hasn't been installed yet.
  4. It would revert to the existing behavior of using the bundled version.

I dont think that this introduces any particular pitfalls, since IME you need to restart VSCode after any kind of npm/yarn/pnpm operation anyway.
Furthermore, in most TypeScript projects, you would also get unrelated errors about ESLint/Prettier/Jest not being installed, meaning that there are other things that would tip you off to the situation in the first place.

mkantor — Today at 2:19 PM
i guess thought it'd be surprising that running npm install would implicitly change the version of the compiler VSCode uses, but you're right that similar things already happen in other contexts, so maybe not

@Zamiell
Copy link
Author

Zamiell commented Jan 29, 2023

Some more discussion from the TypeScript Discord:

𝚠𝚎𝚋𝚜𝚝𝚛𝚊𝚗𝚍 — Today at 2:27 PM
[Talking about how the proposed changed can probably only work if the workspace is trusted.]
I think that's a fair compromise, anyway. To load the package.json typescript file only when the workspace is trusted

Zamiel — Today at 2:28 PM
I think VSCode can actually skip looking at package.json altogether, because it doesn't matter what the version of TypeScript is, it can just automatically use whatever version happens to be located in project/node_modules/typescript.

𝚠𝚎𝚋𝚜𝚝𝚛𝚊𝚗𝚍 — Today at 2:29 PM
I'd actually prefer it to only use the package.json version. If there's a mismatch report an error.
such mismatches shouldn't occur in general
it also means that you could have global installs for various typescript versions
and use them without trusting the workspace

webstrand brings up a great point here!

As an entirely-separate-but-semi-related feature request, we propose that VSCode should throw an error (or warning) when the currently-loaded version of TypeScript does not match the specific version of TypeScript in the project's package.json file. (This should happen regardless of whether the currently-loaded version of TypeScript is coming from the built-in VSCode bundled version, or whether it is coming from the version in the project's own directory.)

Having this functionality would be a great boon for troubleshooting the kind of mismatch errors that this issue is concerned with.

@c-ehrlich
Copy link

Thanks for opening this. I do think this is quite challenging and there are a lot of edge case behaviours that would need to be accounted for. Nonetheless it feels intuitively correct that if a project specifies TS version x, the default should not be to override this with workspace TS version y.

@mjbvz
Copy link
Contributor

mjbvz commented Feb 1, 2023

We've discussed this previously but decided against this for a few reasons:

  • Workspace versions of TS tend to get out of date. Old TS versions have bugs and performance issues that have often been fixed by our bundled version. We don't make any fixes to old TS versions and issues reports from these old versions are also generally not helpful

  • While there are cases where using a different TS version for editing vs compiling matters, it usually doesn't.

    On your note:

    VSCode was very slow to update the version of TypeScript

    The stable version of VS Code typically picks up the latest stable Typescript within one to two weeks. The latest TS is typically in VS Code insiders after one day. It sounds like in your case you were trying to use features from an upcoming TS beta or RC

    I don't think it's a big obstacle for advanced users who need the latest TS right away to switch to use the workspace version of TS

The compromise is the setting you already called out: typescript.enablePromptUseWorkspaceTsdk. This makes it easier for advanced users to switch, without effecting the experience of the vast majority of users who do not need to switch to the workspace version (and for whom switching could actually result in a worse user experience)

@mjbvz mjbvz closed this as completed Feb 1, 2023
@mjbvz mjbvz added typescript Typescript support issues *as-designed Described behavior is as designed labels Feb 1, 2023
@Zamiell
Copy link
Author

Zamiell commented Feb 1, 2023

@mjbvz Thanks for the reply.

While it is sad to hear that the default behavior will not be changed, what do you think about adding the warning that webstrand proposed?

Specifically, we propose that VSCode should throw an popup/error/warning when the currently loaded TypeScript version inside VSCode does not match the one in the project's package.json file.

The idea here is that if this happens, the end-user would immediately know that something is wrong. And then they would know that they should either:
a) update their dependencies / package.json file to the latest TypeScript version so that it matches the VSCode bundled version, or
b) manually specify their actual intended version by clicking on the "4.9.4" in the bottom-right-hand corner (which will also write an entry to "typescript.tsdk" AFAIK).

Having this popup/error/warning would go a really long way towards preventing the miserable troubleshooting scenarios described in the original post.

@starball5
Copy link

@github-actions github-actions bot locked and limited conversation to collaborators Mar 18, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
*as-designed Described behavior is as designed typescript Typescript support issues
Projects
None yet
Development

No branches or pull requests

4 participants