Description
I noticed a discrepancy between vscode (tsserver directly) and typescript-language-server.
Given the files:
/// file:App.tsx
import React from "react";
export function App() {
return (
<div>
<Link />
</div>
);
}
/// file:Link.tsx
import React from "react";
export function Link() {
return <div />;
}
We will receive a diagnostic over Link
in App.tsx
:
When placing the cursor after the k
in Link
in App.tsx
, vscode makes a getCodeFixes
request that appears as follows:
Info 653 [11:43:26.587] request:
{
"seq": 146,
"type": "request",
"command": "getCodeFixes",
"arguments": {
"file": "/Users/brady/Desktop/test/App.tsx",
"startLine": 7,
"startOffset": 8,
"endLine": 7,
"endOffset": 12,
"errorCodes": [
2304
]
}
}
Info 654 [11:43:26.587] forEachExternalModuleToImportFrom autoImportProvider: 0.13391613960266113
Perf 655 [11:43:26.588] 146::getCodeFixes: elapsed time (in milliseconds) 1.2297
Info 656 [11:43:26.588] response:
{"seq":0,"type":"response","command":"getCodeFixes","request_seq":146,"success":true,"body":[{"fixName":"import","description":"Add import from \"./Link\"","changes":[{"fileName":"/Users/brady/Desktop/test/App.tsx","textChanges":[{"start":{"line":3,"offset":1},"end":{"line":3,"offset":1},"newText":"import { Link } from \"./Link\";\n"}]}]}]}
As you can see, the requested start and end positions are the range of the diagnostic:
"startLine": 7,
"startOffset": 8,
"endLine": 7,
"endOffset": 12,
And as such, a code fix to import Link
is returned from tsserver.
This is because vscode's implementation uses the diagnostic's range as the range: https://github.com/microsoft/vscode/blob/fd4b93963e6456d09175410ea1cc84cb796ad241/extensions/typescript-language-features/src/languageFeatures/quickFix.ts#L330
Compare this with typescript-language-server
, which requests the following:
Info 92 [15:48:08.612] request:
{"seq":12,"type":"request","command":"getCodeFixes","arguments":{"file":"/home/runner/HardtofindScratchyEngineers/src/App.tsx","startLine":7,"startOffset":12,"endLine":7,"endOffset":12,"errorCodes":[2304]}}
Perf 93 [15:48:08.613] 12::getCodeFixes: elapsed time (in milliseconds) 1.4205
Info 94 [15:48:08.613] response:
{"seq":0,"type":"response","command":"getCodeFixes","request_seq":12,"success":true,"body":[]}
As you can see the requested start and end positions are simply from the cursor position and thus tsserver returns no results:
"startLine": 7,
"startOffset": 12,
"endLine": 7,
"endOffset": 12,
Now, it could be argued that this bug is instead on tsserver to include the trailing position in getCodeFixes
range, such that a request from 7:12-7:12 would still receive the fix. But I think this could be an opportunity to update typescript-language-server
to adjust its request range instead.
I don't think this is something the client can handle - as if the client sent the range of the diagnostic as its range, it would be misrepresenting the current editor selection, and potentially receive other invalid code actions.
Thanks for your consideration!