Open-Source Wikis

/

TypeScript

/

Systems

/

Language service

microsoft/TypeScript

Language service

The library that powers IDE features: completions, quick info, signature help, find-all-references, rename, go-to-definition, refactorings, code fixes, formatting, document highlights, and more. The language service is what tsserver exposes over its JSON protocol.

Source

The language service lives entirely under src/services/. About 168 TypeScript files totalling ~65,000 lines.

Subdirectory Role
services/services.ts (3,622 lines) Top-level createLanguageService; method dispatch
services/types.ts (75k lines effective) Public language-service interface types
services/completions.ts (6,173 lines) Completion provider
services/findAllReferences.ts (2,803 lines) Find-all-references and rename
services/goToDefinition.ts (1,000+ lines) Definition / type-definition / implementation
services/codeFixProvider.ts + services/codefixes/ Code-fix registry and ~80 code-fix providers
services/refactorProvider.ts + services/refactors/ Refactoring registry and 16 refactorings
services/formatting/ Token-level formatter
services/signatureHelp.ts Parameter-hint provider
services/symbolDisplay.ts "Hover" / quickInfo formatting
services/textChanges.ts (~87k effective lines) High-level edit builder used by every refactor
services/utilities.ts (~170k effective lines) Service-side shared utilities

Purpose

The language service answers IDE queries against a Program. It is:

  • Synchronous. Every entry point returns immediately. The client (typically tsserver) handles cancellation via a CancellationToken.
  • Stateless across queries. Each call resolves the latest program, asks for what it needs, and returns. State is held by the host (file snapshots) and the program.
  • Host-driven. A LanguageServiceHost (provided by tsserver or the embedder) supplies getScriptFileNames(), getScriptVersion(fileName), getScriptSnapshot(fileName), getCurrentDirectory(), getCompilationSettings(), getCustomTransformers?, etc.

Key abstractions

Symbol Role
createLanguageService(host, documentRegistry?, syntaxOnlyOrLanguageServiceMode?) Public factory
LanguageService The query interface — ~70 methods
LanguageServiceHost Filesystem-like host the service queries
DocumentRegistry Cache of parsed source files shared across services
LanguageServiceMode Semantic, PartialSemantic, Syntactic — controls which features are available
Completions.getCompletionsAtPosition Completion entry
findAllReferences.Core.getReferencedSymbolsForNode References entry
goToDefinition.getDefinitionAtPosition Definition entry
getCodeFixesAtPosition Code fixes
getApplicableRefactors / getEditsForRefactor Refactors

Architecture

graph TD
    Host["LanguageServiceHost"] --> Service["createLanguageService"]
    Service --> Program["program.ts: createProgram"]
    Program --> Checker["checker.ts"]
    Service --> Completions["services/completions.ts"]
    Service --> Refs["services/findAllReferences.ts"]
    Service --> Defs["services/goToDefinition.ts"]
    Service --> Fixes["services/codefixes/*"]
    Service --> Refactors["services/refactors/*"]
    Service --> Format["services/formatting/*"]
    Service --> Symbol["services/symbolDisplay.ts"]
    Completions --> Checker
    Refs --> Checker
    Defs --> Checker
    Fixes --> TextChanges["services/textChanges.ts"]
    Refactors --> TextChanges

Most providers follow the same shape:

  1. Snap the current Program from the host.
  2. Locate the AST node at the query position.
  3. Ask the checker for the relevant symbol/type/signature.
  4. Translate the result into the public-API shape.

textChanges.ChangeTracker is the workhorse for any feature that returns edits. It records insertions, replacements, and deletions in terms of AST nodes and emits a FileTextChanges[] at the end. Code fixes and refactors share this primitive.

DocumentRegistry

createDocumentRegistry() returns a process-wide cache of parsed SourceFiles keyed by filename, version, and CompilerOptions. When two LanguageServices share the same registry (which tsserver arranges), they avoid re-parsing the same files. The registry knows when a file's snapshot version has changed and can invalidate appropriately.

Code fixes

Code fixes are auto-suggestions targeted at specific diagnostic codes. Each fix is a small TypeScript file under src/services/codefixes/ (over 80 of them) that:

  • Registers itself against one or more error codes via codefix.registerCodeFix({ errorCodes, getCodeActions, fixIds }).
  • Implements getCodeActions(context) to produce a CodeFixAction with description, changes (file edits), and an optional fixId for "fix all".
  • Optionally implements getAllCodeActions for the "fix all instances of this in the file/project" path.

Examples: addMissingAsync.ts, addMissingAwait.ts, convertToAsyncFunction.ts, convertToEsModule.ts, fixUnusedIdentifier.ts, importFixes.ts (~115k effective lines on its own — auto-import is huge).

Refactors

Refactors are user-initiated transformations: extract function, extract type, convert function-to-class, move-to-file, inline variable, etc. Each lives under src/services/refactors/ and registers via refactor.registerRefactor. The provider returns a list of ApplicableRefactorInfo for the cursor position; the editor presents them as code actions; selecting one calls getEditsForRefactor which returns RefactorEditInfo with FileTextChanges.

Modes

LanguageServiceMode controls which features are available:

  • Semantic — full type-checking. Default.
  • PartialSemantic — type-checks only the open file's program; cross-file features are best-effort.
  • Syntactic — no type-checking at all; only AST-based features (formatting, brace matching, syntactic completions). Used for very fast preview workflows.

Plugins

Language-service plugins wrap a LanguageService, adding or overriding behaviour. They're loaded by tsserver based on compilerOptions.plugins in tsconfig.json or --globalPlugins. Each plugin is an npm package whose entry point exports init(modules) returning { create(info) }. The wrapped service is what tsserver then uses for that project. See src/server/project.ts.

Integration points

  • Used by tsserver (src/server/) — every editor command becomes a method call.
  • Used by VS Code's bundled "JavaScript" support (yes, JS too — TypeScript's JS support is the language service in --allowJs mode).
  • Used by tools like tsc-alias, bundlers, and IDEs that don't speak the JSON protocol but want IntelliSense.

Entry points for modification

See features/language-service-features and features/refactors-and-codefixes for the user-facing capabilities.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Language service – TypeScript wiki | Factory