Skip to content

Commit

Permalink
mark exports as "can only bind to them"
Browse files Browse the repository at this point in the history
  • Loading branch information
dummdidumm committed Apr 18, 2024
1 parent 811b1ce commit ade7c5b
Show file tree
Hide file tree
Showing 12 changed files with 149 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
},
"severity": 1,
"source": "ts",
"message": "Type 'Component' is not assignable to type 'OtherComponent'.\n Types of property '$$prop_def' are incompatible.\n Type 'StripBindable<PropsWithChildren<{ prop: boolean; }, any>>' is not assignable to type 'StripBindable<PropsWithChildren<{ prop: string; }, any>>'.\n Type 'StripBindable<WithBindings<{ prop: boolean; }>>' is not assignable to type 'StripBindable<PropsWithChildren<{ prop: string; }, any>>'.",
"message": "Type 'Component' is not assignable to type 'OtherComponent'.\n The types of '$$prop_def.prop' are incompatible between these types.\n Type 'boolean' is not assignable to type 'string'.",
"code": 2322,
"tags": []
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<script lang="ts">
export let value = 'implicitly bindable';
export function bind_and_prop() {
return true;
}
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script lang="ts">
let { readonly, can_bind = $bindable() }: { readonly?: string; can_bind?: string } = $props();
export function only_bind() {
return true;
}
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[
{
"code": 2322,
"message": "Type 'Binding<string>' is not assignable to type 'string'.",
"range": {
"end": {
"character": 20,
"line": 23
},
"start": {
"character": 12,
"line": 23
}
},
"severity": 1,
"source": "ts",
"tags": []
},
{
"code": 2322,
"message": "Type '() => boolean' is not assignable to type 'Binding<() => boolean>'.",
"range": {
"end": {
"character": 17,
"line": 24
},
"start": {
"character": 8,
"line": 24
}
},
"severity": 1,
"source": "ts",
"tags": []
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<script lang="ts">
import Legacy from './Legacy.svelte';
import Runes from './Runes.svelte';
let bind_and_prop: () => boolean;
let value = '';
let only_bind: () => boolean;
let can_bind = '';
let readonly = ''
</script>

<!-- ok -->
<Legacy bind:bind_and_prop />
<Legacy bind:value />
<Legacy {value} />
<Legacy {bind_and_prop} />
<Runes bind:can_bind />
<Runes {can_bind} />
<Runes {readonly} />
<Runes bind:only_bind />

<!-- error in Svelte 5 -->
<Runes bind:readonly />
<Runes {only_bind} />
22 changes: 17 additions & 5 deletions packages/svelte2tsx/src/svelte2tsx/nodes/ExportedNames.ts
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,12 @@ export class ExportedNames {
? `__sveltets_2_Bindings<${this.$props.type}, ${this.$props.bindings.map((b) => `"${b}"`).join('|')}>`
: this.$props.type) +
(others.length
? ' & { ' + this.createReturnElementsType(others).join(',') + ' }'
? ' & { ' +
this.createReturnElementsType(others, undefined, [
'import("svelte").Binding<',
'>'
]).join(',') +
' }'
: '')
);
}
Expand All @@ -630,7 +635,7 @@ export class ExportedNames {
return (
this.$props.comment.slice(0, idx) +
(others.length > 0
? `{${this.createReturnElementsType(others, false)}} & `
? `{${this.createReturnElementsType(others, false, ['import("svelte").Binding<', '>'])}} & `
: '') +
(has_bindings ? '__sveltets_2_Bindings<' : '') +
this.$props.comment.slice(idx, end) +
Expand Down Expand Up @@ -700,16 +705,23 @@ export class ExportedNames {
});
}

private createReturnElementsType(names: Array<[string, ExportedName]>, addDoc = true) {
private createReturnElementsType(
names: Array<[string, ExportedName]>,
addDoc = true,
wrapWith?: [string, string]
) {
const wrap = wrapWith
? (str: string) => `${wrapWith[0]}${str}${wrapWith[1]}`
: (str: string) => str;
return names.map(([key, value]) => {
const identifier = `${value.doc && addDoc ? `\n${value.doc}` : ''}${
value.identifierText || key
}${value.required ? '' : '?'}`;
if (!value.type) {
return `${identifier}: typeof ${key}`;
return `${identifier}: ${wrap(`typeof ${key}`)}`;
}

return `${identifier}: ${value.type}`;
return `${identifier}: ${wrap(value.type)}`;
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ declare const __propDef: {
props: {
foo: string;
bar?: import("svelte").Bindable<number>;
baz?: () => void;
baz?: import("svelte").Binding<() => void>;
};
events: {
[evt: string]: CustomEvent<any>;
Expand All @@ -17,7 +17,7 @@ export default class TestRunes extends SvelteComponent<TestRunesProps, TestRunes
constructor(options?: import("svelte").ComponentConstructorOptions<{
foo: string;
bar?: import("svelte").Bindable<number>;
baz?: () => void;
baz?: import("svelte").Binding<() => void>;
}>);
get baz(): () => void;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
///<reference types="svelte" />
;function render() {

/** @typedef {{form: boolean, data: true }} $$ComponentProps *//** @type {$$ComponentProps} */
let { form, data } = $props();
/** @type {any} */
const snapshot = {};
;
async () => {};
return { props: /** @type {{snapshot?: import("svelte").Binding<typeof snapshot>} & $$ComponentProps} */({}), slots: {}, events: {} }}

export default class Page__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(['snapshot'], __sveltets_2_with_any_event(render()))) {
constructor(options = __sveltets_2_runes_constructor(__sveltets_2_partial(['snapshot'], __sveltets_2_with_any_event(render())))) { super(options); }
get snapshot() { return __sveltets_2_nonNullable(this.$$prop_def.snapshot) }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
///<reference types="svelte" />
;function render() {

let/** @typedef {{ form: import('./$types.js').ActionData, data: import('./$types.js').PageData }} $$ComponentProps *//** @type {$$ComponentProps} */ { form, data } = $props();
const snapshot/*Ωignore_startΩ*/: import('./$types.js').Snapshot/*Ωignore_endΩ*/ = {};
;
async () => {};
return { props: /** @type {{snapshot?: import("svelte").Binding<typeof snapshot>} & $$ComponentProps} */({}), slots: {}, events: {} }}

export default class Page__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(['snapshot'], __sveltets_2_with_any_event(render()))) {
constructor(options = __sveltets_2_runes_constructor(__sveltets_2_partial(['snapshot'], __sveltets_2_with_any_event(render())))) { super(options); }
get snapshot() { return __sveltets_2_nonNullable(this.$$prop_def.snapshot) }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
///<reference types="svelte" />
;function render() {

const snapshot: any = {};;type $$ComponentProps = {form: boolean, data: true };
let { form, data }:$$ComponentProps = $props();
;
async () => {};
return { props: {} as any as $$ComponentProps & { snapshot?: import("svelte").Binding<any> }, slots: {}, events: {} }}

export default class Page__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_with_any_event(render())) {
constructor(options = __sveltets_2_runes_constructor(__sveltets_2_with_any_event(render()))) { super(options); }
get snapshot() { return __sveltets_2_nonNullable(this.$$prop_def.snapshot) }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
///<reference types="svelte" />
;function render() {

const snapshot/*Ωignore_startΩ*/: import('./$types.js').Snapshot/*Ωignore_endΩ*/ = {};/*Ωignore_startΩ*/;type $$ComponentProps = { form: import('./$types.js').ActionData, data: import('./$types.js').PageData };/*Ωignore_endΩ*/
let { form, data }: $$ComponentProps = $props();
;
async () => {};
return { props: {} as any as $$ComponentProps & { snapshot?: import("svelte").Binding<typeof snapshot> }, slots: {}, events: {} }}

export default class Page__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_with_any_event(render())) {
constructor(options = __sveltets_2_runes_constructor(__sveltets_2_with_any_event(render()))) { super(options); }
get snapshot() { return __sveltets_2_nonNullable(this.$$prop_def.snapshot) }
}

0 comments on commit ade7c5b

Please sign in to comment.