mirror of
https://github.com/withastro/astro.git
synced 2025-12-05 18:56:38 -06:00
fix: svelte 5 prop types (#14934)
This commit is contained in:
5
.changeset/olive-lands-try.md
Normal file
5
.changeset/olive-lands-try.md
Normal file
@@ -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.
|
||||
@@ -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",
|
||||
|
||||
@@ -7,12 +7,22 @@ export function toTSX(code: string, className: string): string {
|
||||
`;
|
||||
|
||||
try {
|
||||
let tsx = svelte2tsx(code, { mode: 'ts' }).code;
|
||||
tsx = '/// <reference types="svelte2tsx/svelte-shims" />\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<typeof $$$$Component>): 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;
|
||||
}
|
||||
|
||||
1
packages/integrations/svelte/svelte-shims.d.ts
vendored
Normal file
1
packages/integrations/svelte/svelte-shims.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import 'svelte2tsx/svelte-shims-v4';
|
||||
18
packages/integrations/svelte/test/check.test.js
Normal file
18
packages/integrations/svelte/test/check.test.js
Normal file
@@ -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',
|
||||
);
|
||||
});
|
||||
});
|
||||
13
packages/integrations/svelte/test/fixtures/async-rendering/src/components/PropTypes.svelte
vendored
Normal file
13
packages/integrations/svelte/test/fixtures/async-rendering/src/components/PropTypes.svelte
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<script lang="ts">
|
||||
interface Props {
|
||||
name: string;
|
||||
age?: number;
|
||||
bold?: boolean;
|
||||
}
|
||||
|
||||
let { name, age = 0, bold = false }: Props = $props();
|
||||
</script>
|
||||
|
||||
<p class:bold={bold}>
|
||||
Hello {name}, you are {age} years old.
|
||||
</p>
|
||||
5
packages/integrations/svelte/test/fixtures/async-rendering/tsconfig.json
vendored
Normal file
5
packages/integrations/svelte/test/fixtures/async-rendering/tsconfig.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
7
packages/integrations/svelte/test/fixtures/prop-types/astro.config.mjs
vendored
Normal file
7
packages/integrations/svelte/test/fixtures/prop-types/astro.config.mjs
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import { defineConfig } from 'astro/config';
|
||||
import svelte from '@astrojs/svelte';
|
||||
|
||||
export default defineConfig({
|
||||
srcDir: './types',
|
||||
integrations: [svelte()]
|
||||
});
|
||||
16
packages/integrations/svelte/test/fixtures/prop-types/package.json
vendored
Normal file
16
packages/integrations/svelte/test/fixtures/prop-types/package.json
vendored
Normal file
@@ -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"
|
||||
}
|
||||
}
|
||||
1
packages/integrations/svelte/test/fixtures/prop-types/svelte.config.js
vendored
Normal file
1
packages/integrations/svelte/test/fixtures/prop-types/svelte.config.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export default {};
|
||||
5
packages/integrations/svelte/test/fixtures/prop-types/tsconfig.json
vendored
Normal file
5
packages/integrations/svelte/test/fixtures/prop-types/tsconfig.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
13
packages/integrations/svelte/test/fixtures/prop-types/types/PropTypes.svelte
vendored
Normal file
13
packages/integrations/svelte/test/fixtures/prop-types/types/PropTypes.svelte
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<script lang="ts">
|
||||
interface Props {
|
||||
name: string;
|
||||
age?: number;
|
||||
bold?: boolean;
|
||||
}
|
||||
|
||||
let { name, age = 0, bold = false }: Props = $props();
|
||||
</script>
|
||||
|
||||
<p class:bold={bold}>
|
||||
Hello {name}, you are {age} years old.
|
||||
</p>
|
||||
16
packages/integrations/svelte/test/fixtures/prop-types/types/index.astro
vendored
Normal file
16
packages/integrations/svelte/test/fixtures/prop-types/types/index.astro
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
import PropTypes from './PropTypes.svelte';
|
||||
---
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<title>Astro</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Astro</h1>
|
||||
<PropTypes name="Test" age="invalid" bold />
|
||||
</body>
|
||||
</html>
|
||||
12
pnpm-lock.yaml
generated
12
pnpm-lock.yaml
generated
@@ -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':
|
||||
|
||||
Reference in New Issue
Block a user