The TypeScript formatting service produces whitespace and indentation edits for TypeScript and JavaScript source text. It is part of the Language Service layer (see page 4) and operates purely on text ranges, returning TextChange[] arrays that editors apply to source buffers. It does not alter the AST.
For automated code formatting of the TypeScript codebase itself (including TypeScript, JSON, and YAML support), the project uses dprint.
TypeScript uses dprint for repository-wide code consistency. The configuration is managed via .dprint.jsonc and integrated into the hereby build system.
.dprint.jsonc)The configuration defines specific rules for TypeScript, JSON, and YAML, and specifies the WASM plugins used for formatting.
| Plugin | Version | Source |
|---|---|---|
| TypeScript | 0.93.4 | https://plugins.dprint.dev/typescript-0.93.4.wasm |
| JSON | 0.19.4 | https://plugins.dprint.dev/json-0.19.4.wasm |
| YAML | v0.5.0 | https://plugins.dprint.dev/g-plane/pretty_yaml-v0.5.0.wasm |
Key formatting constraints defined in .dprint.jsonc:
indentWidth: 4, lineWidth: 1000, newLineKind: "auto" [.dprint.jsonc:3-5].nextControlFlowPosition: "nextLine") and crlf newlines [.dprint.jsonc:8-15].node_modules, built/, tests/, lib/, and generated files (e.g., **/*.generated.*) [.dprint.jsonc:40-52].Sources: [.dprint.jsonc:1-61], [package.json:42-43]
Formatting is exposed as a top-level command in the repository.
npm run format executes dprint fmt [package.json:99].The internal formatting system (used by the Language Service) is implemented under src/services/formatting/ and is composed of five cooperating components:
| Component | File | Role |
|---|---|---|
FormatContext | formatting.ts | Bundles FormatCodeSettings, RulesMap, and FormattingHost for a formatting pass [src/services/formatting/formatting.ts:82-86] |
FormattingContext | formattingContext.ts | Holds the current token pair being evaluated; provides lazy-computed layout predicates |
FormattingScanner | formattingScanner.ts | Walks source text token-by-token, collecting leading/trailing trivia [src/services/formatting/formattingScanner.ts:29-42] |
| Rules engine | rule.ts, rules.ts, rulesMap.ts | Defines and indexes all space/newline rules keyed by token-pair |
SmartIndenter | smartIndenter.ts | Computes indentation levels for nodes and cursor positions [src/services/formatting/smartIndenter.ts:62-82] |
Architecture diagram: Formatting components
Sources: [src/services/formatting/formatting.ts:82-86], [src/services/formatting/formattingScanner.ts:29-42], [src/services/formatting/smartIndenter.ts:62-82]
The public-facing formatting functions each correspond to an editor trigger and a value of the FormattingRequestKind enum.
| Function | Trigger | FormattingRequestKind |
|---|---|---|
formatOnEnter | Enter key pressed | FormatOnEnter |
formatOnSemicolon | ; typed | FormatOnSemicolon |
formatOnOpeningCurly | { typed | FormatOnOpeningCurlyBrace |
formatOnEnter adjusts the span to cover the previous line and the trailing non-whitespace of the newly created line [src/services/formatting/formatting.ts:160-187]. formatOnSemicolon uses findImmediatelyPrecedingTokenOfKind to locate the triggering token [src/services/formatting/formatting.ts:190-193].
Pipeline flow diagram
Sources: [src/services/formatting/formatting.ts:160-201], [src/services/formatting/smartIndenter.ts:82-159]
Rule and RuleActionA Rule describes a transformation to apply between two adjacent tokens. RuleAction values [src/services/formatting/rules.ts:7-10] include:
InsertSpace, InsertNewLine, DeleteSpace, DeleteToken, InsertTrailingSemicolon.RuleSpec and getAllRules()A RuleSpec pairs a Rule with the left and right TokenRange it applies to [src/services/formatting/rules.ts:37-41]. The function getAllRules() returns rules in priority groups, including high priority common rules (e.g., IgnoreBeforeComment) and user-configurable rules [src/services/formatting/rules.ts:44-99].
Sources: [src/services/formatting/rules.ts:37-124]
FormattingScannerFormattingScanner is the token-level cursor used by the formatter. It wraps two underlying TypeScript scanner instances: standardScanner and jsxScanner [src/services/formatting/formattingScanner.ts:25-26].
Key interface methods [src/services/formatting/formattingScanner.ts:29-42]:
advance(): Move forward, collecting trivia.readTokenInfo(n: Node): Return the current token with trivia; may rescan for context (e.g., RescanJsxIdentifier) [src/services/formatting/formattingScanner.ts:176-187].Sources: [src/services/formatting/formattingScanner.ts:25-187]
SmartIndenterSmartIndenter computes indentation column values based on IndentStyle (None, Block, or Smart) [src/services/formatting/smartIndenter.ts:82-91].
nodeWillIndentChild determines if a parent node (like ClassDeclaration or Block) should indent its children [src/services/formatting/smartIndenter.ts:10-13].