What is typescript-language-server?
The typescript-language-server is an implementation of the Language Server Protocol (LSP) for TypeScript. It provides a range of features to enhance the development experience in editors and IDEs by offering functionalities like auto-completion, go-to-definition, and more.
What are typescript-language-server's main functionalities?
Auto-completion
This code sets up a basic TypeScript Language Server that provides auto-completion suggestions. When the user types, the server can suggest completions like 'console.log'.
const { createConnection, TextDocuments } = require('vscode-languageserver');
const connection = createConnection();
const documents = new TextDocuments();
connection.onInitialize(() => {
return {
capabilities: {
textDocumentSync: documents.syncKind,
completionProvider: {
resolveProvider: true
}
}
};
});
connection.onCompletion(() => {
return [
{
label: 'console.log',
kind: 1,
data: 1
}
];
});
connection.listen();
Go-to-definition
This code sets up a TypeScript Language Server that provides go-to-definition functionality. When the user requests the definition of a symbol, the server responds with the location of the definition.
const { createConnection, TextDocuments } = require('vscode-languageserver');
const connection = createConnection();
const documents = new TextDocuments();
connection.onInitialize(() => {
return {
capabilities: {
textDocumentSync: documents.syncKind,
definitionProvider: true
}
};
});
connection.onDefinition((params) => {
return {
uri: params.textDocument.uri,
range: {
start: { line: 0, character: 0 },
end: { line: 0, character: 10 }
}
};
});
connection.listen();
Diagnostics
This code sets up a TypeScript Language Server that provides diagnostics. It scans the document for 'TODO' comments and reports them as warnings.
const { createConnection, TextDocuments, Diagnostic, DiagnosticSeverity } = require('vscode-languageserver');
const connection = createConnection();
const documents = new TextDocuments();
connection.onInitialize(() => {
return {
capabilities: {
textDocumentSync: documents.syncKind
}
};
});
documents.onDidChangeContent((change) => {
const diagnostics = [];
const text = change.document.getText();
const pattern = /TODO/g;
let match;
while ((match = pattern.exec(text))) {
diagnostics.push({
severity: DiagnosticSeverity.Warning,
range: {
start: change.document.positionAt(match.index),
end: change.document.positionAt(match.index + match[0].length)
},
message: `TODO found: ${match[0]}`,
source: 'ex'
});
}
connection.sendDiagnostics({ uri: change.document.uri, diagnostics });
});
connection.listen();
Other packages similar to typescript-language-server
vscode-json-languageserver
The vscode-json-languageserver is a Language Server Protocol implementation for JSON. It provides similar functionalities like auto-completion, go-to-definition, and diagnostics but is specifically tailored for JSON files. Compared to typescript-language-server, it is focused on JSON rather than TypeScript.
vscode-css-languageserver-bin
The vscode-css-languageserver-bin is a Language Server Protocol implementation for CSS. It offers features like auto-completion, go-to-definition, and diagnostics for CSS files. While typescript-language-server is for TypeScript, this package is specialized for CSS.
vscode-html-languageserver-bin
The vscode-html-languageserver-bin is a Language Server Protocol implementation for HTML. It provides functionalities such as auto-completion, go-to-definition, and diagnostics for HTML files. This package is similar to typescript-language-server but is designed for HTML.
![Discord](https://img.shields.io/discord/873659987413573634)
TypeScript Language Server
Language Server Protocol implementation for TypeScript wrapping tsserver
.
![https://nodei.co/npm/typescript-language-server.png?downloads=true&downloadRank=true&stars=true](https://nodei.co/npm/typescript-language-server.png?downloads=true&downloadRank=true&stars=true)
Based on concepts and ideas from https://github.com/prabirshrestha/typescript-language-server and originally maintained by TypeFox
Maintained by a community of contributors like you
Installing
npm install -g typescript-language-server
Running the language server
typescript-language-server --stdio
CLI Options
Usage: typescript-language-server [options]
Options:
-V, --version output the version number
--stdio use stdio (required option)
--log-level <log-level> A number indicating the log level (4 = log, 3 = info, 2 = warn, 1 = error). Defaults to `3`.
--tsserver-log-file <tsServerLogFile> Specify a tsserver log file. example: --tsserver-log-file=ts-logs.txt
--tsserver-log-verbosity <verbosity> Specify tsserver log verbosity (off, terse, normal, verbose). Defaults to `normal`. example: --tsserver-log-verbosity=verbose
--tsserver-path <path> Specify path to tsserver directory. example: --tsserver-path=/Users/me/typescript/lib/
-h, --help output usage information
Note: The path passed to --tsserver-path
should ideally be a path to the /.../typescript/lib/
directory and not to the shell script /.../node_modules/.bin/tsserver
or tsserver
. Though for backward-compatibility reasons, the server will try to do the right thing even when passed a path to the shell script.
initializationOptions
The language server accepts various settings through the initializationOptions
object passed through the initialize
request. Refer to your LSP client's documentation on how to set these. Here is the list of supported options:
Setting | Type | Description |
---|
hostInfo | string | Information about the host, for example "Emacs 24.4" or "Sublime Text v3075" . Default: undefined |
disableAutomaticTypingAcquisition | boolean | Disables tsserver from automatically fetching missing type definitions (@types packages) for external modules. |
logVerbosity | string | The verbosity level of the information printed in the log by tsserver . Accepts values: "off" , "terse" , "normal" , "requesttime" , "verbose" . Default: undefined ("off" ). |
maxTsServerMemory | number | The maximum size of the V8's old memory section in megabytes (for example 4096 means 4GB). The default value is dynamically configured by Node so can differ per system. Increase for very big projects that exceed allowed memory usage. Default: undefined |
npmLocation | string | Specifies the path to the NPM executable used for Automatic Type Acquisition. |
plugins | object[] | An array of { name: string, location: string } objects for registering a Typescript plugins. Default: [] |
preferences | object | Preferences passed to the Typescript (tsserver ) process. See below for more info. |
The preferences
object is an object specifying preferences for the internal tsserver
process. Those options depend on the version of Typescript used but at the time of writing Typescript v4.4.3 contains these options:
interface UserPreferences {
disableSuggestions: boolean;
quotePreference: "auto" | "double" | "single";
includeCompletionsForModuleExports: boolean;
includeCompletionsForImportStatements: boolean;
includeCompletionsWithSnippetText: boolean;
includeCompletionsWithInsertText: boolean;
includeAutomaticOptionalChainCompletions: boolean;
includeCompletionsWithClassMemberSnippets: boolean;
allowIncompleteCompletions: boolean;
importModuleSpecifierPreference: "shortest" | "project-relative" | "relative" | "non-relative";
importModuleSpecifierEnding: "auto" | "minimal" | "index" | "js";
allowTextChangesInNewFiles: boolean;
lazyConfiguredProjectsFromExternalProject: boolean;
providePrefixAndSuffixTextForRename: boolean;
provideRefactorNotApplicableReason: boolean;
allowRenameOfImportPath: boolean;
includePackageJsonAutoImports: "auto" | "on" | "off";
jsxAttributeCompletionStyle: "auto" | "braces" | "none";
displayPartsForJSDoc: boolean;
generateReturnInDocTemplate: boolean;
}
From the preferences
options listed above, this server explicilty sets the following options (all other options use their default values):
{
allowIncompleteCompletions: true,
allowRenameOfImportPath: true,
allowTextChangesInNewFiles: true,
displayPartsForJSDoc: true,
generateReturnInDocTemplate: true,
includeAutomaticOptionalChainCompletions: true,
includeCompletionsForImportStatements: true,
includeCompletionsForModuleExports: true,
includeCompletionsWithClassMemberSnippets: true,
includeCompletionsWithInsertText: true,
includeCompletionsWithSnippetText: true,
jsxAttributeCompletionStyle: "auto",
}
workspace/didChangeConfiguration
Some of the preferences can be controlled through the workspace/didChangeConfiguration
notification. Below is a list of supported options that can be passed. Note that the settings are specified separately for the typescript and javascript files so [language]
can be either javascript
or typescript
.
[language].format.baseIndentSize: number;
[language].format.convertTabsToSpaces: boolean;
[language].format.indentSize: number;
[language].format.indentStyle: 'None' | 'Block' | 'Smart';
[language].format.insertSpaceAfterCommaDelimiter: boolean;
[language].format.insertSpaceAfterConstructor: boolean;
[language].format.insertSpaceAfterFunctionKeywordForAnonymousFunctions: boolean;
[language].format.insertSpaceAfterKeywordsInControlFlowStatements: boolean;
[language].format.insertSpaceAfterOpeningAndBeforeClosingEmptyBraces: boolean;
[language].format.insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: boolean;
[language].format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: boolean;
[language].format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: boolean;
[language].format.insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: boolean;
[language].format.insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: boolean;
[language].format.insertSpaceAfterSemicolonInForStatements: boolean;
[language].format.insertSpaceAfterTypeAssertion: boolean;
[language].format.insertSpaceBeforeAndAfterBinaryOperators: boolean;
[language].format.insertSpaceBeforeFunctionParenthesis: boolean;
[language].format.insertSpaceBeforeTypeAnnotation: boolean;
[language].format.newLineCharacter: string;
[language].format.placeOpenBraceOnNewLineForControlBlocks: boolean;
[language].format.placeOpenBraceOnNewLineForFunctions: boolean;
[language].format.semicolons: 'ignore' | 'insert' | 'remove';
[language].format.tabSize: number;
[language].format.trimTrailingWhitespace: boolean;
[language].inlayHints.includeInlayEnumMemberValueHints: boolean;
[language].inlayHints.includeInlayFunctionLikeReturnTypeHints: boolean;
[language].inlayHints.includeInlayFunctionParameterTypeHints: boolean;
[language].inlayHints.includeInlayParameterNameHints: 'none' | 'literals' | 'all';
[language].inlayHints.includeInlayParameterNameHintsWhenArgumentMatchesName: boolean;
[language].inlayHints.includeInlayPropertyDeclarationTypeHints: boolean;
[language].inlayHints.includeInlayVariableTypeHints: boolean;
completions.completeFunctionCalls: boolean;
diagnostics.ignoredCodes: number[];
Code actions on save
Server announces support for the following code action kinds:
source.addMissingImports.ts
- adds imports for used but not imported symbolssource.fixAll.ts
- despite the name, fixes a couple of specific issues: unreachable code, await in non-async functions, incorrectly implemented interfacesource.removeUnused.ts
- removes declared but unused variablessource.organizeImports.ts
- organizes and removes unused imports
This allows editors that support running code actions on save to automatically run fixes associated with those kinds.
Those code actions, if they apply in the current code, should also be presented in the list of "Source Actions" if the editor exposes those.
The user can enable it with a setting similar to (can vary per-editor):
"codeActionsOnSave": {
"source.organizeImports.ts": true,
"source.organizeImports": true,
}
Workspace commands (workspace/executeCommand
)
See LSP specification.
Most of the time, you'll execute commands with arguments retrieved from another request like textDocument/codeAction
. There are some use cases for calling them manually.
Supported commands:
lsp
refers to the language server protocol, tsp
refers to the typescript server protocol.
_typescript.applyWorkspaceEdit
type Arguments = [lsp.WorkspaceEdit]
_typescript.applyCodeAction
type Arguments = [tsp.CodeAction]
_typescript.applyRefactoring
type Arguments = [tsp.GetEditsForRefactorRequestArgs]
_typescript.organizeImports
type Arguments = [string] | [string, { skipDestructiveCodeActions?: boolean }]
_typescript.applyRenameFile
type Arguments = [{ sourceUri: string; targetUri: string; }]
Inlay hints (typescript/inlayHints
) (experimental)
Supports experimental inline hints.
type Request = {
textDocument: TextDocumentIdentifier,
range?: Range,
}
type Response = {
inlayHints: InlayHint[];
}
type InlayHint = {
text: string;
position: lsp.Position;
kind: 'Type' | 'Parameter' | 'Enum';
whitespaceBefore?: boolean;
whitespaceAfter?: boolean;
};
For the request to return any results, some or all of the following options need to be enabled through preferences
:
export interface InlayHintsOptions extends UserPreferences {
includeInlayParameterNameHints: 'none' | 'literals' | 'all';
includeInlayParameterNameHintsWhenArgumentMatchesName: boolean;
includeInlayFunctionParameterTypeHints: boolean;
includeInlayVariableTypeHints: boolean;
includeInlayPropertyDeclarationTypeHints: boolean;
includeInlayFunctionLikeReturnTypeHints: boolean;
includeInlayEnumMemberValueHints: boolean;
}
Callers and callees (textDocument/calls
) (experimental)
Supports showing callers and calles for a given symbol. If the editor has support for appropriate UI, it can generate a tree of callers and calles for a document.
type Request = {
textDocument: TextDocumentIdentifier;
position: Position;
direction?: CallDirection;
}
export enum CallDirection {
Incoming = 'incoming',
Outgoing = 'outgoing',
}
type Result = {
symbol?: DefinitionSymbol;
calls: Call[];
}
interface Call {
location: Location;
symbol: DefinitionSymbol;
}
interface DefinitionSymbol {
name: string;
detail?: string;
kind: SymbolKind;
location: Location;
selectionRange: Range;
}
Supported Protocol features
Development
Build
yarn
Test
yarn test
Watch
yarn watch
Publishing
yarn publish