Skip to content

Commit 1003acc

Browse files
authored
feat: add Snippet type (#9584)
* feat: add Snippet type related to #9447 * one more test
1 parent da15806 commit 1003acc

File tree

6 files changed

+62
-2
lines changed

6 files changed

+62
-2
lines changed

.changeset/shiny-baboons-play.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
feat: add Snippet type

packages/svelte/src/compiler/phases/1-parse/acorn.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import * as acorn from 'acorn';
22
import { walk } from 'zimmerframe';
33
import { tsPlugin } from 'acorn-typescript';
44

5-
// @ts-expect-error
65
const ParserWithTS = acorn.Parser.extend(tsPlugin());
76

87
/**
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Silence the acorn typescript errors through this ambient type definition + tsconfig.json path alias
2+
// That way we can omit `"skipLibCheck": true` and catch other errors in our d.ts files
3+
declare module 'acorn-typescript';

packages/svelte/src/main/public.d.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,19 @@ export type ComponentType<Comp extends SvelteComponent> = (new (
185185
element?: typeof HTMLElement;
186186
};
187187

188+
declare const SnippetReturn: unique symbol;
189+
190+
/**
191+
* The type of a `#snippet` block. You can use it to (for example) express that your component expects a snippet of a certain type:
192+
* ```ts
193+
* let { banner } = $props<{ banner: Snippet<{ text: string }> }>();
194+
* ```
195+
* You can only call a snippet through the `{@render ...}` tag.
196+
*/
197+
export interface Snippet<T = void> {
198+
(arg: T): typeof SnippetReturn;
199+
}
200+
188201
interface DispatchOptions {
189202
cancelable?: boolean;
190203
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import type { Snippet } from 'svelte';
2+
3+
const return_type: ReturnType<Snippet> = null as any;
4+
5+
// @ts-expect-error
6+
const a: Snippet<{ text: string }> = () => {};
7+
// @ts-expect-error
8+
const b: Snippet<boolean> = (a, b) => {
9+
return return_type;
10+
};
11+
// @ts-expect-error
12+
const c: Snippet<boolean> = (a: string) => {
13+
return return_type;
14+
};
15+
// @ts-expect-error
16+
const d: Snippet<boolean> = (a: string, b: number) => {
17+
return return_type;
18+
};
19+
// @ts-expect-error
20+
const e: Snippet = (a: string) => {
21+
return return_type;
22+
};
23+
const f: Snippet = (a) => {
24+
// @ts-expect-error
25+
a?.x;
26+
return return_type;
27+
};
28+
const g: Snippet<boolean> = (a) => {
29+
// @ts-expect-error
30+
a === '';
31+
a === true;
32+
return return_type;
33+
};
34+
const h: Snippet<{ a: true }> = (a) => {
35+
a.a === true;
36+
return return_type;
37+
};
38+
const i: Snippet = () => {
39+
return return_type;
40+
};

packages/svelte/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
"noErrorTruncation": true,
1111
"allowSyntheticDefaultImports": true,
1212
"verbatimModuleSyntax": true,
13-
"skipLibCheck": true,
1413
"types": ["node"],
1514
"strict": true,
1615
"allowJs": true,
1716
"checkJs": true,
1817
"paths": {
18+
"acorn-typescript": ["./src/compiler/phases/1-parse/ambient.d.ts"],
1919
"svelte": ["./src/main/public.d.ts"],
2020
"svelte/action": ["./src/action/public.d.ts"],
2121
"svelte/compiler": ["./src/compiler/public.d.ts"],

0 commit comments

Comments
 (0)