zvelte-check version: 0.2.0
Date: 2026-04-22
We've been evaluating zvelte-check as a drop-in replacement for svelte-check in a large pnpm workspace monorepo with multiple Svelte packages (mix of Svelte 4 and Svelte 5 patterns). svelte-check reports 0 errors across all packages, but zvelte-check reports hundreds of false positives. All fall into 3 categories.
1. CSS/HTML text parsed as TypeScript identifiers
The transformer extracts identifiers from raw AST node source slices before validating them as actual JavaScript expressions. CSS property values, CSS units, and plain HTML text content end up emitted as void name; statements, which tsgo rejects as undefined identifiers.
Examples
Cannot find name 'calc'.
Cannot find name 'rem'.
Cannot find name 'vw'.
Cannot find name 'flex'.
Cannot find name 'container'.
Cannot find name 'hidden'.
Cannot find name 'head'.
Cannot find name 'style'.
Cannot find name 'DevOps'.
Cannot find name 'engineers'.
These come from pages with rich HTML/CSS content — marketing pages, documentation, microsites — where <style> blocks, inline style= attributes, and plain text are present alongside Svelte template expressions.
Expected behavior
CSS values like flex, rem, calc and plain text like Sourcegraph should never be extracted as TypeScript identifiers. Only actual Svelte {expressions} should be.
2. Bad TypeScript syntax from $props() destructuring
The generated .svelte.ts output contains invalid TypeScript for certain $props() patterns, producing syntax errors.
Error patterns
';' expected.
',' expected.
'=' expected.
')' expected.
'=>' expected.
Expression expected.
Property or signature expected.
Failing input patterns
const destructuring (Svelte 5)
<script lang="ts">
interface Props { notes: string[] }
const { notes }: Props = $props()
</script>
zvelte-check appears to only recognize let as the declaration keyword before $props(). When const is used, the transform produces invalid TS output.
Complex $$Props types (Svelte 4)
<script lang="ts">
import type { ComponentProps } from 'svelte'
import FileIcon from './FileIcon.svelte'
type $$Props = { language: string } & Omit<ComponentProps<FileIcon>, 'file'>
export let language: string
</script>
<script lang="ts">
import type { SVGAttributes } from 'svelte/elements'
type $$Props = SVGAttributes<SVGElement> & { svgPath: string; inline?: boolean }
export let svgPath: string
export let inline: boolean = false
</script>
<script lang="ts">
import type { HTMLButtonAttributes } from 'svelte/elements'
type $$Props = { on: boolean } & HTMLButtonAttributes
export let on: boolean
</script>
Complex intersection types, generic types (Omit<...>), and mapped types in $$Props declarations appear to cause the transformer to emit malformed TypeScript.
Expected behavior
Both const and let destructuring with $props() should produce valid TypeScript. Svelte 4 $$Props patterns with complex type expressions should also transform correctly.
3. Missing named exports from *.svelte wildcard module
When one package imports named exports from .svelte files in another package, the wildcard *.svelte ambient module declaration reports that the named export doesn't exist.
Example
Given a component library package that re-exports types from .svelte files:
// @my-org/uikit/src/lib/index.ts
export type { AlertVariant, AlertStyleOverrides } from './components/alert/Alert.svelte'
export type { ButtonSize, ButtonVariant } from './components/button/Button.svelte'
export type { IconComponent, Props } from './components/icon/Icon.svelte'
And a consuming package in the same monorepo:
import { Icon, type IconComponent } from '@my-org/uikit'
zvelte-check reports:
Module '"*.svelte"' has no exported member 'AlertVariant'.
Module '"*.svelte"' has no exported member 'ButtonVariant'.
Module '"*.svelte"' has no exported member 'IconComponent'.
Module '"*.svelte"' has no exported member 'Props'.
Module '"*.svelte"' has no exported member 'ThemeMode'.
Root cause
Only .svelte files in the current workspace are transformed to .svelte.ts with real exports. Files from referenced packages are not transformed, so tsgo falls back to the wildcard *.svelte ambient module stub which only has a default export.
Expected behavior
Named exports from .svelte files in referenced/imported packages should resolve correctly, either by transforming those files too or by generating per-module declarations for known imports.
Environment
- macOS (darwin arm64)
- zvelte-check 0.2.0
- pnpm workspace monorepo
- Mix of Svelte 4 (
export let, type $$Props) and Svelte 5 ($props(), interface Props) patterns
- svelte-check reports 0 errors on the same codebase
zvelte-check version: 0.2.0
Date: 2026-04-22
We've been evaluating zvelte-check as a drop-in replacement for svelte-check in a large pnpm workspace monorepo with multiple Svelte packages (mix of Svelte 4 and Svelte 5 patterns). svelte-check reports 0 errors across all packages, but zvelte-check reports hundreds of false positives. All fall into 3 categories.
1. CSS/HTML text parsed as TypeScript identifiers
The transformer extracts identifiers from raw AST node source slices before validating them as actual JavaScript expressions. CSS property values, CSS units, and plain HTML text content end up emitted as
void name;statements, which tsgo rejects as undefined identifiers.Examples
These come from pages with rich HTML/CSS content — marketing pages, documentation, microsites — where
<style>blocks, inlinestyle=attributes, and plain text are present alongside Svelte template expressions.Expected behavior
CSS values like
flex,rem,calcand plain text likeSourcegraphshould never be extracted as TypeScript identifiers. Only actual Svelte{expressions}should be.2. Bad TypeScript syntax from
$props()destructuringThe generated
.svelte.tsoutput contains invalid TypeScript for certain$props()patterns, producing syntax errors.Error patterns
Failing input patterns
constdestructuring (Svelte 5)zvelte-check appears to only recognize
letas the declaration keyword before$props(). Whenconstis used, the transform produces invalid TS output.Complex
$$Propstypes (Svelte 4)Complex intersection types, generic types (
Omit<...>), and mapped types in$$Propsdeclarations appear to cause the transformer to emit malformed TypeScript.Expected behavior
Both
constandletdestructuring with$props()should produce valid TypeScript. Svelte 4$$Propspatterns with complex type expressions should also transform correctly.3. Missing named exports from
*.sveltewildcard moduleWhen one package imports named exports from
.sveltefiles in another package, the wildcard*.svelteambient module declaration reports that the named export doesn't exist.Example
Given a component library package that re-exports types from
.sveltefiles:And a consuming package in the same monorepo:
zvelte-check reports:
Root cause
Only
.sveltefiles in the current workspace are transformed to.svelte.tswith real exports. Files from referenced packages are not transformed, so tsgo falls back to the wildcard*.svelteambient module stub which only has a default export.Expected behavior
Named exports from
.sveltefiles in referenced/imported packages should resolve correctly, either by transforming those files too or by generating per-module declarations for known imports.Environment
export let,type $$Props) and Svelte 5 ($props(),interface Props) patterns