This page documents the JSDoc services layer of the TypeScript language service, covering comment template generation, tag and parameter completions, and extraction of JSDoc comments and tags for display. These features operate within the language service infrastructure described in Language Service. For general code completions (including how JSDoc completions are surfaced to callers), see Code Completions. For inlay hints and symbol display that consume extracted JSDoc data, see Inlay Hints and Symbol Display.
The JSDoc support layer is implemented primarily in `src/services/jsDoc.ts` It provides four categories of functionality:
| Feature | Entry Point | Consumer |
|---|---|---|
| Doc comment template generation | getDocCommentTemplateAtPosition | Language service getDocCommentTemplateAtPosition |
| JSDoc tag name completions | getJSDocTagNameCompletions, getJSDocTagCompletions | Completions service |
Parameter name completions inside @param | getJSDocParameterNameCompletions | Completions service |
| Comment/tag extraction for display | getJsDocCommentsFromDeclarations, getJsDocTagsFromDeclarations | Hover, signature help, symbol display |
The constant jsDocTagNames src/services/jsDoc.ts97-182 defines the full list of tag names offered in completions. These are drawn from the JSDoc standard and TypeScript-specific extensions:
JSDoc standard tags (selected):
| Tag | Tag | Tag | Tag |
|---|---|---|---|
abstract | author | callback | class |
deprecated | description | enum | example |
extends | fires | module | namespace |
param | property | returns | see |
since | throws | type | typedef |
version | yields |
TypeScript-specific tags:
| Tag | Purpose |
|---|---|
template | Generic type parameter declaration |
overload | Function overload annotation |
satisfies | Type assertion without narrowing |
import | Import type declaration |
inheritdoc | Inherit documentation from parent |
These tag names drive both getJSDocTagNameCompletions (which prefixes each name with @) and getJSDocTagCompletions (which produces the bare name), both returning CompletionEntry[] with ScriptElementKind.keyword and lazy-initialized singleton arrays.
Sources: src/services/jsDoc.ts97-182 src/services/jsDoc.ts374-411
When a user types /** above a declaration, the language service calls getDocCommentTemplateAtPosition to produce a TextInsertion containing a pre-filled JSDoc template with @param and optional @returns lines.
The function only produces a template when the cursor is in a valid position: outside of existing non-empty comments and immediately preceding one of the following declaration kinds:
module.exports = function() {})Sources: src/services/jsDoc.ts451-531 src/services/jsDoc.ts561-626
Doc Comment Template Generation Flow
Sources: src/services/jsDoc.ts476-531
getCommentOwnerInfo calls forEachAncestor on the token at the cursor, delegating to getCommentOwnerInfoWorker for each ancestor node. The worker returns a CommentOwnerInfo object:
interface CommentOwnerInfo {
readonly commentOwner: Node;
readonly parameters?: readonly ParameterDeclaration[];
readonly hasReturn?: boolean;
}
For variable statements, it calls getRightHandSideOfAssignment to unwrap parenthesized expressions and reach the underlying FunctionExpression, ArrowFunction, or class constructor. For PropertyAssignment, it delegates to the initializer.
The hasReturn flag is set when options.generateReturnInDocTemplate is true and the target node either: has an expression body (arrow function), or has a block body containing at least one return statement (detected via forEachReturnStatement).
Sources: src/services/jsDoc.ts553-646
For a function with parameters, the template looks like:
/**
*
* @param x
* @param y
* @returns
*/
.js files, each @param line includes a type placeholder: {any} (or {...any} for rest parameters)./** */ is produced instead.caretOffset in the returned TextInsertion positions the cursor after the opening /**\n * .Sources: src/services/jsDoc.ts509-530 src/services/jsDoc.ts541-551
Two functions produce tag name completions from the jsDocTagNames array:
| Function | Entry format | Used when |
|---|---|---|
getJSDocTagNameCompletions | "param", "returns", … | Cursor is after @ in a JSDoc comment |
getJSDocTagCompletions | "@param", "@returns", … | Cursor is at the start of a tag position |
Both return cached CompletionEntry[] arrays (initialized once) with kind: ScriptElementKind.keyword and sortText: Completions.SortText.LocationPriority.
getJSDocTagNameCompletionDetails and getJSDocTagCompletionDetails are aliases; both return a minimal CompletionEntryDetails with the tag name as display text and empty documentation.
Sources: src/services/jsDoc.ts374-411
getJSDocParameterNameCompletions(tag: JSDocParameterTag): CompletionEntry[] provides completions for the parameter name position within a @param tag. It:
JSDoc node, then to the containing function-like node.fn.parameters, filtering out parameters already referenced by other @param tags in the same comment.nameThusFar).kind: ScriptElementKind.parameterElement.Only simple Identifier parameter names are surfaced; destructured patterns are excluded.
Sources: src/services/jsDoc.ts413-449
Completion Dispatch Diagram
Sources: src/services/jsDoc.ts374-449
These functions are called by hover, signature help, and symbol display to convert JSDoc AST nodes into SymbolDisplayPart[] arrays for presentation in editors.
getJsDocCommentsFromDeclarationsAccepts a list of Declaration nodes (e.g., all overloads of a symbol) and returns merged comment text as SymbolDisplayPart[].
Key behaviors:
forEachUnique to deduplicate declarations that share the same JSDoc node (e.g., Array<string> and Array<number> both contributing Array.length).JSDoc blocks that contain only @typedef or @callback tags and no @param/@return — these are treated as type declarations, not function documentation.@inheritDoc / @inheritdoc by appending the tag's own comment after the primary comment text.isIdenticalListOfDisplayParts.lineBreakPart() separators.Sources: src/services/jsDoc.ts187-222
getJsDocTagsFromDeclarationsAccepts a list of Declaration nodes and returns JSDocTagInfo[], one entry per tag across all declarations.
Each JSDocTagInfo has:
name: the tag name text (e.g., "param", "returns")text: SymbolDisplayPart[] | undefined computed by getCommentDisplayPartsFor tags with nested property tags (e.g., @param obj followed by @param obj.x), getJSDocPropertyTagsInfo recursively traverses JSDocTypeLiteral.jsDocPropertyTags to produce flattened entries.
Sources: src/services/jsDoc.ts247-276
getCommentDisplayParts — Per-Tag Display LogicEach tag kind is rendered differently:
| Tag kind | Display |
|---|---|
JSDocParameterTag | parameterNamePart(name) + space + comment |
JSDocPropertyTag | propertyNamePart(name) + space + comment |
JSDocTemplateTag | constraint text + type parameter names + comment |
JSDocTypeTag, JSDocSatisfiesTag | type expression text |
JSDocTypedefTag, JSDocCallbackTag | name node text |
JSDocImplementsTag, JSDocAugmentsTag | .class node text |
JSDocThrowsTag | type expression if present, else comment |
JSDocSeeTag | name node text if present, else comment |
| All others | raw comment text |
Sources: src/services/jsDoc.ts288-355
The following diagram maps the AST structures that JSDoc services operate on:
JSDoc AST Node Relationships
Sources: src/services/jsDoc.ts553-626 src/services/jsDoc.ts228-244
Full JSDoc Service Data Flow
Sources: src/services/jsDoc.ts187-267 src/services/jsDoc.ts374-449 src/services/jsDoc.ts476-531
JSDoc service behavior is verified by fourslash tests under tests/cases/fourslash/. Key test files:
| Test file | What it covers |
|---|---|
docCommentTemplateFunctionWithParameters.ts | Template with @param for typed parameters |
docCommentTemplateClassDeclMethods01.ts | Templates for method overloads with varying parameter counts |
docCommentTemplateObjectLiteralMethods01.ts | Templates for object literal method shorthand and assigned functions |
docCommentTemplateVariableStatements01.ts | Templates for var/let/const with function initializers |
docCommentTemplateVariableStatements03.ts | Arrow function and class expression initializers |
docCommentTemplateConstructor01.ts | Constructor overload templates |
docCommentTemplateNamespacesAndModules02.ts | Only top-level namespace gets a template; nested dotted names do not |
docCommentTemplateInterfacesEnumsAndTypeAliases.ts | Interfaces, enums, type aliases, and property signatures |
docCommentTemplateJsSpecialPropertyAssignment.ts | module.exports and namespace property assignment in .js files |
docCommentTemplateIndentation.ts | Indentation carried from the cursor's line |
docCommentTemplateInSingleLineComment.ts | No template inside // single-line comments |
docCommentTemplateInsideFunctionDeclaration.ts | No template when cursor is inside the declaration body |
docCommentTemplateRegex.ts | No template when cursor is inside a regex literal |
docCommentTemplate_insideEmptyComment.ts | Template generated inside an empty /** */; no template inside a non-empty one |
Tests use verify.docCommentTemplateAt(marker, caretOffset, expectedText) and verify.noDocCommentTemplateAt(marker) from the fourslash harness.
Sources: tests/cases/fourslash/docCommentTemplateFunctionWithParameters.ts tests/cases/fourslash/docCommentTemplateClassDeclMethods01.ts tests/cases/fourslash/docCommentTemplateVariableStatements01.ts
Refresh this wiki
This wiki was recently refreshed. Please wait 4 days to refresh again.