From 4264a3657155ca95c9bdaa7b8d0340422212374d Mon Sep 17 00:00:00 2001 From: Antony Faris Date: Fri, 5 Dec 2025 05:05:28 -0500 Subject: [PATCH] fix: svelte 5 prop types (#14934) --- .changeset/olive-lands-try.md | 5 +++++ packages/integrations/svelte/package.json | 4 +++- packages/integrations/svelte/src/editor.cts | 22 ++++++++++++++----- .../integrations/svelte/svelte-shims.d.ts | 1 + .../integrations/svelte/test/check.test.js | 18 +++++++++++++++ .../src/components/PropTypes.svelte | 13 +++++++++++ .../fixtures/async-rendering/tsconfig.json | 5 +++++ .../test/fixtures/prop-types/astro.config.mjs | 7 ++++++ .../test/fixtures/prop-types/package.json | 16 ++++++++++++++ .../test/fixtures/prop-types/svelte.config.js | 1 + .../test/fixtures/prop-types/tsconfig.json | 5 +++++ .../prop-types/types/PropTypes.svelte | 13 +++++++++++ .../fixtures/prop-types/types/index.astro | 16 ++++++++++++++ pnpm-lock.yaml | 12 ++++++++++ 14 files changed, 131 insertions(+), 7 deletions(-) create mode 100644 .changeset/olive-lands-try.md create mode 100644 packages/integrations/svelte/svelte-shims.d.ts create mode 100644 packages/integrations/svelte/test/check.test.js create mode 100644 packages/integrations/svelte/test/fixtures/async-rendering/src/components/PropTypes.svelte create mode 100644 packages/integrations/svelte/test/fixtures/async-rendering/tsconfig.json create mode 100644 packages/integrations/svelte/test/fixtures/prop-types/astro.config.mjs create mode 100644 packages/integrations/svelte/test/fixtures/prop-types/package.json create mode 100644 packages/integrations/svelte/test/fixtures/prop-types/svelte.config.js create mode 100644 packages/integrations/svelte/test/fixtures/prop-types/tsconfig.json create mode 100644 packages/integrations/svelte/test/fixtures/prop-types/types/PropTypes.svelte create mode 100644 packages/integrations/svelte/test/fixtures/prop-types/types/index.astro diff --git a/.changeset/olive-lands-try.md b/.changeset/olive-lands-try.md new file mode 100644 index 0000000000..a166dad7ad --- /dev/null +++ b/.changeset/olive-lands-try.md @@ -0,0 +1,5 @@ +--- +'@astrojs/svelte': patch +--- + +Fixes an issue where Svelte 5 components used in Astro files would not have proper type checking and IntelliSense. diff --git a/packages/integrations/svelte/package.json b/packages/integrations/svelte/package.json index f130b4d662..1d70d8b097 100644 --- a/packages/integrations/svelte/package.json +++ b/packages/integrations/svelte/package.json @@ -24,10 +24,12 @@ "./editor": "./dist/editor.cjs", "./client.js": "./dist/client.svelte.js", "./server.js": "./dist/server.js", + "./svelte-shims.d.ts": "./svelte-shims.d.ts", "./package.json": "./package.json" }, "files": [ - "dist" + "dist", + "svelte-shims.d.ts" ], "scripts": { "build": "astro-scripts build \"src/**/*.ts\" && astro-scripts build \"src/editor.cts\" --force-cjs --no-clean-dist && tsc", diff --git a/packages/integrations/svelte/src/editor.cts b/packages/integrations/svelte/src/editor.cts index 42a72913d2..eff44c5411 100644 --- a/packages/integrations/svelte/src/editor.cts +++ b/packages/integrations/svelte/src/editor.cts @@ -7,12 +7,22 @@ export function toTSX(code: string, className: string): string { `; try { - let tsx = svelte2tsx(code, { mode: 'ts' }).code; - tsx = '/// \n' + tsx; - result = tsx.replace( - 'export default class extends __sveltets_2_createSvelte2TsxComponent(', - `export default function ${className}__AstroComponent_(_props: typeof Component.props): any {}\nlet Component = `, - ); + let tsx = svelte2tsx(code, { mode: 'ts', isTsFile: true }).code; + tsx = "import '@astrojs/svelte/svelte-shims.d.ts';\n" + tsx; + + // New svelte2tsx output (Svelte 5) + if (tsx.includes('export default $$Component;')) { + result = tsx.replace( + 'export default $$Component;', + `export default function ${className}__AstroComponent_(_props: import('svelte').ComponentProps): any {}`, + ); + } else { + // Old svelte2tsx output + result = tsx.replace( + 'export default class extends __sveltets_2_createSvelte2TsxComponent(', + `export default function ${className}__AstroComponent_(_props: typeof Component.props): any {}\nlet Component = `, + ); + } } catch { return result; } diff --git a/packages/integrations/svelte/svelte-shims.d.ts b/packages/integrations/svelte/svelte-shims.d.ts new file mode 100644 index 0000000000..34136e827c --- /dev/null +++ b/packages/integrations/svelte/svelte-shims.d.ts @@ -0,0 +1 @@ +import 'svelte2tsx/svelte-shims-v4'; diff --git a/packages/integrations/svelte/test/check.test.js b/packages/integrations/svelte/test/check.test.js new file mode 100644 index 0000000000..b389f1f99b --- /dev/null +++ b/packages/integrations/svelte/test/check.test.js @@ -0,0 +1,18 @@ +import assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; +import { fileURLToPath } from 'node:url'; +import { cli } from '../../../astro/test/test-utils.js'; + +describe('Svelte Check', () => { + it('should fail check on type error', async () => { + const root = fileURLToPath(new URL('./fixtures/prop-types/', import.meta.url)); + const { getResult } = cli('check', '--root', root); + const { exitCode, stdout } = await getResult(); + + assert.equal(exitCode, 1, 'Expected check to fail (exit code 1)'); + assert.ok( + stdout.includes(`Type 'string' is not assignable to type 'number'`), + 'Expected specific type error message', + ); + }); +}); diff --git a/packages/integrations/svelte/test/fixtures/async-rendering/src/components/PropTypes.svelte b/packages/integrations/svelte/test/fixtures/async-rendering/src/components/PropTypes.svelte new file mode 100644 index 0000000000..777d76f9cf --- /dev/null +++ b/packages/integrations/svelte/test/fixtures/async-rendering/src/components/PropTypes.svelte @@ -0,0 +1,13 @@ + + +

+ Hello {name}, you are {age} years old. +

diff --git a/packages/integrations/svelte/test/fixtures/async-rendering/tsconfig.json b/packages/integrations/svelte/test/fixtures/async-rendering/tsconfig.json new file mode 100644 index 0000000000..8bf91d3bb9 --- /dev/null +++ b/packages/integrations/svelte/test/fixtures/async-rendering/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "astro/tsconfigs/strict", + "include": [".astro/types.d.ts", "**/*"], + "exclude": ["dist"] +} diff --git a/packages/integrations/svelte/test/fixtures/prop-types/astro.config.mjs b/packages/integrations/svelte/test/fixtures/prop-types/astro.config.mjs new file mode 100644 index 0000000000..494643028b --- /dev/null +++ b/packages/integrations/svelte/test/fixtures/prop-types/astro.config.mjs @@ -0,0 +1,7 @@ +import { defineConfig } from 'astro/config'; +import svelte from '@astrojs/svelte'; + +export default defineConfig({ + srcDir: './types', + integrations: [svelte()] +}); diff --git a/packages/integrations/svelte/test/fixtures/prop-types/package.json b/packages/integrations/svelte/test/fixtures/prop-types/package.json new file mode 100644 index 0000000000..253b7559c4 --- /dev/null +++ b/packages/integrations/svelte/test/fixtures/prop-types/package.json @@ -0,0 +1,16 @@ +{ + "name": "svelte-prop-types", + "type": "module", + "version": "0.0.1", + "scripts": { + "dev": "astro dev", + "build": "astro build", + "preview": "astro preview", + "astro": "astro" + }, + "dependencies": { + "@astrojs/svelte": "^7.2.2", + "astro": "^5.16.0", + "svelte": "^5.43.14" + } +} diff --git a/packages/integrations/svelte/test/fixtures/prop-types/svelte.config.js b/packages/integrations/svelte/test/fixtures/prop-types/svelte.config.js new file mode 100644 index 0000000000..ff8b4c5632 --- /dev/null +++ b/packages/integrations/svelte/test/fixtures/prop-types/svelte.config.js @@ -0,0 +1 @@ +export default {}; diff --git a/packages/integrations/svelte/test/fixtures/prop-types/tsconfig.json b/packages/integrations/svelte/test/fixtures/prop-types/tsconfig.json new file mode 100644 index 0000000000..8bf91d3bb9 --- /dev/null +++ b/packages/integrations/svelte/test/fixtures/prop-types/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "astro/tsconfigs/strict", + "include": [".astro/types.d.ts", "**/*"], + "exclude": ["dist"] +} diff --git a/packages/integrations/svelte/test/fixtures/prop-types/types/PropTypes.svelte b/packages/integrations/svelte/test/fixtures/prop-types/types/PropTypes.svelte new file mode 100644 index 0000000000..777d76f9cf --- /dev/null +++ b/packages/integrations/svelte/test/fixtures/prop-types/types/PropTypes.svelte @@ -0,0 +1,13 @@ + + +

+ Hello {name}, you are {age} years old. +

diff --git a/packages/integrations/svelte/test/fixtures/prop-types/types/index.astro b/packages/integrations/svelte/test/fixtures/prop-types/types/index.astro new file mode 100644 index 0000000000..fc88715213 --- /dev/null +++ b/packages/integrations/svelte/test/fixtures/prop-types/types/index.astro @@ -0,0 +1,16 @@ +--- +import PropTypes from './PropTypes.svelte'; +--- + + + + + + + Astro + + +

Astro

+ + + diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 70db9bd830..66b96896e1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6024,6 +6024,18 @@ importers: specifier: ^5.43.14 version: 5.43.14 + packages/integrations/svelte/test/fixtures/prop-types: + dependencies: + '@astrojs/svelte': + specifier: ^7.2.2 + version: link:../../.. + astro: + specifier: ^5.16.0 + version: link:../../../../../astro + svelte: + specifier: ^5.43.14 + version: 5.43.14 + packages/integrations/vercel: dependencies: '@astrojs/internal-helpers':