svelte.ts

Svelte component analysis helpers.

Extracts metadata from Svelte components using svelte2tsx transformations:

  • Component props with types and JSDoc
  • Component-level documentation
  • Type information

Workflow: Transform Svelte to TypeScript via svelte2tsx, parse the transformed TypeScript with the TS Compiler API, extract component-level JSDoc from original source.

Svelte 5 only: The svelte2tsx output format changed significantly between versions. This module requires Svelte 5+ and will throw a clear error if an older version is detected. There is no Svelte 4 compatibility layer.

@see typescript-exports.ts for analyzeExports, extractModuleComment @see typescript-extract-shared.ts for parseGenericParam, filterDocumentedProperties, createExtractContext @see typescript-extract-type-json.ts for resolveTypeInfo, referenceSymbolName, tupleElements, restElementForms @see tsdoc.ts for parseComment, applyToDeclaration @see source.ts for SourceFileInfo, getComponentName

view source

Declarations
#

13 declarations

analyzeSvelteModule
#

svelte.ts view source

(sourceFile: SourceFileInfo & { dependents?: readonly string[] | undefined; }, modulePath: string, checker: TypeChecker, options: ModuleSourceOptions, diagnostics: ({ ...; } | ... 14 more ... | { ...; })[], program: Program, virtualFile: SvelteVirtualFile, aliasRegistry?: AliasRegistry | undefined): ModuleAnalysis | undefined import {analyzeSvelteModule} from 'svelte-docinfo/svelte.js';

Analyze a Svelte module using checker-backed analysis.

Requires the svelte2tsx virtual output to be included in the TypeScript program (via createAnalysisProgram({ virtualFiles })). Provides full type resolution for:

  • Imported prop types (let {x}: ImportedProps = $props())
  • <script module> exports (constants, types, re-exports)
  • Star exports and re-exports from Svelte files

sourceFile

the original Svelte source file

type SourceFileInfo & { dependents?: readonly string[] | undefined; }

modulePath

module path relative to source root; feeds ModuleJson.path and the component name, never Diagnostic.file (which is project-root-relative — a different base)

type string

checker

TypeScript type checker (from the program containing virtual files)

type TypeChecker

options

module source options for path extraction

diagnostics

diagnostics collector for non-fatal issues

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

program

TypeScript program containing the virtual file

type Program

virtualFile

pre-transformed virtual file data

aliasRegistry?

the analyzed set's alias registry (see buildAliasRegistry), or undefined when no pre-pass ran

optional

returns

ModuleAnalysis | undefined

module analysis with declarations, re-exports, and star exports; undefined if the virtual file is not found in the program

extractHtmlModuleComment
#

svelte.ts view source

(svelteSource: string): string | undefined import {extractHtmlModuleComment} from 'svelte-docinfo/svelte.js';

Extract @module comment from HTML comments in Svelte source.

Scans all <!-- ... --> comments for one containing @module at the start of a line. This allows @component and @module to coexist as separate HTML comments. Works for template-only components.

svelteSource

the full Svelte source code

type string

returns

string | undefined

the cleaned module comment text, or undefined if no @module HTML comment found

extractModuleScriptContent
#

svelte.ts view source

(svelteSource: string): string | undefined import {extractModuleScriptContent} from 'svelte-docinfo/svelte.js';

Extract the content of the module <script> tag from Svelte source.

Counterpart of extractScriptContent: matches only module scripts, so the two partition a source's script tags consistently.

svelteSource

type string

returns

string | undefined

the module script tag content, or undefined if no module script is found

extractScriptContent
#

svelte.ts view source

(svelteSource: string): string | undefined import {extractScriptContent} from 'svelte-docinfo/svelte.js';

Extract the content of the main <script> tag from Svelte source — commented-out scripts skipped, module scripts (<script module>, <script context="module">) excluded.

svelteSource

type string

returns

string | undefined

the script tag content, or undefined if no matching script tag is found

extractSnippetParameters
#

svelte.ts view source

(snippetType: Type, checker: TypeChecker, aliasRegistry: AliasRegistry | undefined, writtenNode?: TypeNode | undefined): { ...; }[] import {extractSnippetParameters} from 'svelte-docinfo/svelte.js';

Extract structured parameters from a Snippet<[...]> type.

Snippet is an interface, so type arguments are on TypeReference (accessed via checker.getTypeArguments), not on aliasTypeArguments (which is only for type aliases).

Returns full ParameterJson input objects (with optional and rest always set) for runtime consistency with extractSignatureParameters in typescript-extract-shared.ts. Optional tuple elements are widened to include undefined — under exactOptionalPropertyTypes too, unlike properties — so the element type is stripped unconditionally via getTypeSignature and optional: true carries it alone. Rest elements report like rest signature parameters — rest: true with the printed array form (...rest: B[] carries B[]) — and a variadic spread (...T) carries the spread type itself, mirroring the structured typeInfo tuple (buildTuple). Callers pass the bare Snippet<...> TypeReference — a union wrapping it (optional widening, | null) reports no type arguments.

snippetType

type Type

checker

type TypeChecker

aliasRegistry

the analyzed set's alias registry, or undefined when no pre-pass ran — feeds typeInfo name recovery like the prop-level tree

type AliasRegistry | undefined

writtenNode?

the written annotation the snippet type came from, when one exists — feeds typeInfo name recovery, the same node the caller hands the prop-level tree so the two projections can't disagree

type TypeNode
optional

returns

{ name: string; type: string; typeInfo?: TypeJson | undefined; optional?: boolean | undefined; rest?: boolean | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]

array of parameter info for the snippet's tuple type arguments, or [] for bare Snippet / Snippet<[]>

extractSvelteModuleComment
#

svelte.ts view source

(scriptContent: string): string | undefined import {extractSvelteModuleComment} from 'svelte-docinfo/svelte.js';

Extract module-level comment from Svelte script content.

Parses the script content as TypeScript and delegates to extractModuleComment for the shared @module tag detection logic. Works on either script's content — instance <script> and <script module> (see extractScriptContent/extractModuleScriptContent).

scriptContent

the content of a <script> or <script module> tag

type string

returns

string | undefined

the cleaned module comment text, or undefined if none found

isSnippetReturnType
#

svelte.ts view source

(returnType: string): boolean import {isSnippetReturnType} from 'svelte-docinfo/svelte.js';

Check if a return type string matches svelte2tsx's snippet return type pattern.

svelte2tsx transforms exported snippets into arrow functions with ReturnType<import('svelte').Snippet> as the return type annotation. The resolved return type includes unique symbol (from Svelte's non-exported SnippetReturn unique symbol) intersected with the branded render message. We match on both parts to avoid false positives — the branded message alone could theoretically be crafted by user code, but the unique symbol intersection cannot since SnippetReturn is not exported from svelte.

returnType

type string

returns

boolean

isSnippetType
#

svelte.ts view source

(type: Type, checker: TypeChecker): boolean import {isSnippetType} from 'svelte-docinfo/svelte.js';

Whether a checker type is a Snippet instantiation, structurally: a named generic instantiation (referenceSymbolName) named Snippet that carries a call signature — by construction the same shape the TypeJson builder classifies as a Snippet reference.

Callers pass the bare type — a union wrapping the Snippet reference (optional widening, | null) doesn't match, and neither does an intersection (Snippet<[]> & {...}); strip or walk members first.

type

type Type

checker

type TypeChecker

returns

boolean

remapVirtualDiagnosticPositions
#

svelte.ts view source

(diagnostics: ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[], virtualFiles: Iterable<...>): void import {remapVirtualDiagnosticPositions} from 'svelte-docinfo/svelte.js';

Remap diagnostic positions emitted against svelte2tsx virtuals back to original .svelte positions, in place.

Extractors locate diagnostics via getNodeLocation, which reads whatever source file the node lives in — for a <script module> declaration that's the virtual. normalizeDiagnosticPaths later rewrites file to the .svelte path but has no position input, so without this pass the published combination is the original file with the virtual's line — actively misleading. Runs over the whole batch keyed by file, so a diagnostic emitted against *another* component's virtual (a rename re-export re-analyzes its canonical in the canonical's own source file) remaps through that virtual's map.

Must run before normalizeDiagnosticPaths, which strips the virtual suffix this pass matches on. An unmappable position (no source map, or a node svelte2tsx synthesized) drops line/column — absence over a virtual line.

diagnostics

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

virtualFiles

type Iterable<SvelteVirtualFile>

returns

void

mutates

  • diagnostics — — rewrites `line`/`column` on virtual-file entries

SvelteVirtualFile
#

svelte.ts view source

SvelteVirtualFile import type {SvelteVirtualFile} from 'svelte-docinfo/svelte.js';

Pre-transformed Svelte virtual file data.

Produced by transformSvelteSource and consumed by analyzeSvelteModule to provide checker-backed analysis of Svelte components.

virtualPath

Path used for the virtual file in the TypeScript program.

type string

content

svelte2tsx transformed TypeScript content.

type string

sourceMap

Source map for position mapping back to the original .svelte file.

type TraceMap | null

scriptKind

Parser treatment for the virtual: ts.ScriptKind.JS for JS-only components (no lang="ts"), so the checker reads their JSDoc types — the parse tolerates the TS-only statements svelte2tsx emits (a grammar diagnostic, never surfaced) — else ts.ScriptKind.TS. The single encoding of the script language: ComponentDeclarationJson.lang is derived from it at output.

type ScriptKind

synthesizeSnippetTypeSignature
#

svelte.ts view source

(parameters: { name: string; type: string; typeInfo?: TypeJson | undefined; optional?: boolean | undefined; rest?: boolean | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]): string import {synthesizeSnippetTypeSignature} from 'svelte-docinfo/svelte.js';

Synthesize a Snippet<[...]> type string from structured parameters.

Used for kind: 'snippet' declarations where the raw svelte2tsx type is implementation noise. Renders the normalized form — an optional parameter as b?: number, matching the structured parameter fields rather than the checker's widened b?: number | undefined, and a rest parameter with its ... marker (Svelte compile-errors rest parameters in {#snippet}, but analysis never runs that check — svelte2tsx passes them through, so the invalid-but-parseable case renders faithfully rather than dropping the marker).

parameters

type { name: string; type: string; typeInfo?: TypeJson | undefined; optional?: boolean | undefined; rest?: boolean | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]

returns

string

TransformResult
#

svelte.ts view source

TransformResult import type {TransformResult} from 'svelte-docinfo/svelte.js';

Result of transformSvelteSource — a virtual file (when transform succeeded) plus any ingest-time diagnostics produced during the transform.

virtual is undefined when svelte2tsx threw; in that case diagnostics contains a transform_failed entry. When the transform succeeded but source map construction failed, virtual is populated and diagnostics contains a source_map_failed entry. The session's owned-entry stores both — the virtual (or transformFailed: true flag) and the ingest diagnostics.

virtual

type SvelteVirtualFile | undefined

diagnostics

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

transformSvelteSource
#

svelte.ts view source

(sourceFile: SourceFileInfo): TransformResult import {transformSvelteSource} from 'svelte-docinfo/svelte.js';

Pre-transform a Svelte source file via svelte2tsx.

Produces a SvelteVirtualFile containing the transformed TypeScript content and source map. The virtual file can be included in a TypeScript program (via createAnalysisProgram({ virtualFiles })) so that the checker can resolve imported types, <script module> exports, and re-exports.

Errors at ingest are returned via diagnostics rather than thrown:

  • svelte2tsx throws → transform_failed, virtual: undefined
  • source map construction fails → source_map_failed, virtual populated

Diagnostic file paths are the original .svelte source ID; downstream normalization rewrites them to project-root-relative form.

sourceFile

the Svelte source file with content loaded

returns

TransformResult

virtual file data (or undefined on transform failure) plus ingest diagnostics

throws

  • Error - if Svelte version is below 5 (checked once on first call)

Depends on
#

Imported by
#