-
-
Notifications
You must be signed in to change notification settings - Fork 202
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: better type checking for bindings in Svelte 5 (#2477)
#1392 This adds enhanced type checking for bindings in Svelte 5: We're not only passing the variable in, we're also assigning the value of the component property back to the variable. That way, we can catch type errors like the child binding having a wider type as the input we give it. It's done for Svelte 5 only because it's a) easier there b) doesn't break as much code (people who upgrade can then also upgrade the types, or use type assertions in the template, which is only possible in Svelte 5). There's one limitation: Because of how the transformation works, we cannot infer generics. In other words, we will not catch type errors for bindings that rely on a generic type. The combination of generics + bindings is probably rare enough that this is okay, and we can revisit this later to try to find a way to make it work, if it comes up. Also note that this does not affect DOM element bindings like <input bind:value={...} />, this is only about component bindings.
- Loading branch information
1 parent
ec5fef4
commit 8c080cf
Showing
13 changed files
with
116 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
...est/plugins/typescript/features/diagnostics/fixtures/bindings-two-way-check/Legacy.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<script lang="ts"> | ||
export let legacy1: string = ''; | ||
export let legacy2: number | string = ''; | ||
</script> | ||
|
||
{legacy1} | ||
{legacy2} |
6 changes: 6 additions & 0 deletions
6
...test/plugins/typescript/features/diagnostics/fixtures/bindings-two-way-check/Runes.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<script lang="ts"> | ||
let { runes1 = $bindable(), runes2 = $bindable() }: { runes1: string, runes2: string | number } = $props(); | ||
</script> | ||
|
||
{runes1} | ||
{runes2} |
6 changes: 6 additions & 0 deletions
6
...ugins/typescript/features/diagnostics/fixtures/bindings-two-way-check/RunesGeneric.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<script lang="ts" generics="T"> | ||
let { foo, bar = $bindable() }: { foo: T, bar?: T } = $props(); | ||
</script> | ||
|
||
{foo} | ||
{bar} |
36 changes: 36 additions & 0 deletions
36
...ns/typescript/features/diagnostics/fixtures/bindings-two-way-check/expected_svelte_5.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
[ | ||
{ | ||
"code": 2322, | ||
"message": "Type 'string | number' is not assignable to type 'string'.\n Type 'number' is not assignable to type 'string'.", | ||
"range": { | ||
"end": { | ||
"character": 28, | ||
"line": 17 | ||
}, | ||
"start": { | ||
"character": 28, | ||
"line": 17 | ||
} | ||
}, | ||
"severity": 1, | ||
"source": "ts", | ||
"tags": [] | ||
}, | ||
{ | ||
"code": 2322, | ||
"message": "Type 'string | number' is not assignable to type 'string'.\n Type 'number' is not assignable to type 'string'.", | ||
"range": { | ||
"end": { | ||
"character": 45, | ||
"line": 18 | ||
}, | ||
"start": { | ||
"character": 45, | ||
"line": 18 | ||
} | ||
}, | ||
"severity": 1, | ||
"source": "ts", | ||
"tags": [] | ||
} | ||
] |
19 changes: 19 additions & 0 deletions
19
...test/plugins/typescript/features/diagnostics/fixtures/bindings-two-way-check/input.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<script lang="ts"> | ||
import Legacy from './Legacy.svelte'; | ||
import Runes from './Runes.svelte'; | ||
import RunesGeneric from './RunesGeneric.svelte'; | ||
let legacy = ''; | ||
let runes = ''; | ||
let foo: string | number; | ||
</script> | ||
|
||
<!-- ok --> | ||
<Legacy bind:legacy1={legacy} /> | ||
<Runes bind:runes1={runes} bind:runes2={(runes as any)} /> | ||
<!-- bail on generics --> | ||
<RunesGeneric {foo} bind:bar={runes} /> | ||
|
||
<!-- error in Svelte 5 --> | ||
<Legacy bind:legacy2={legacy} /> | ||
<Runes bind:runes1={runes} bind:runes2={runes} /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
<script> | ||
export let value; | ||
<script lang="ts"> | ||
import MyComponent from './ComponentB.svelte' | ||
let value: Date | ||
$: console.log('value:', value) | ||
</script> | ||
|
||
{#if value} | ||
<input bind:value on:change /> | ||
{/if} | ||
|
||
<MyComponent bind:value /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 2 additions & 2 deletions
4
packages/svelte2tsx/test/htmlx2jsx/samples/binding-bare/expected-svelte5.js
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
8 changes: 4 additions & 4 deletions
8
packages/svelte2tsx/test/htmlx2jsx/samples/binding/expected-svelte5.js
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
2 changes: 1 addition & 1 deletion
2
packages/svelte2tsx/test/htmlx2jsx/samples/editing-binding/expected-svelte5.js
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.