From 5dfeef27bbeb3c5652a754cbf475840b027bbab5 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Wed, 8 Mar 2023 15:15:49 +0100 Subject: [PATCH 1/2] (fix) remove overzealous $$Props check The check if exports are assignable to $$Props is removed because a component should be allowed to use less props than defined (it just ignores them) --- .../src/svelte2tsx/nodes/ExportedNames.ts | 13 ++++--------- .../samples/ts-$$Props-interface/expectedv2.ts | 2 +- .../samples/ts-$$Props-type/expectedv2.ts | 2 +- .../samples/ts-$$Props-with-$$props/expectedv2.ts | 2 +- 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/packages/svelte2tsx/src/svelte2tsx/nodes/ExportedNames.ts b/packages/svelte2tsx/src/svelte2tsx/nodes/ExportedNames.ts index d0cfc58de..c9f3729c4 100644 --- a/packages/svelte2tsx/src/svelte2tsx/nodes/ExportedNames.ts +++ b/packages/svelte2tsx/src/svelte2tsx/nodes/ExportedNames.ts @@ -353,21 +353,16 @@ export class ExportedNames { if (this.uses$$Props) { const lets = names.filter(([, { isLet }]) => isLet); const others = names.filter(([, { isLet }]) => !isLet); - // We need to check both ways: - // - The check if exports are assignable to $$Props is necessary to make sure - // no props are missing. Use Partial<$$Props> in case $$props is used. // - The check if $$Props is assignable to exports is necessary to make sure no extraneous props // are defined and that no props are required that should be optional - // __sveltets_2_ensureRightProps needs to be declared in a way that doesn't affect the type result of props + // - The check if exports are assignable to $$Props is not done because a component should be allowed + // to use less props than defined (it just ignores them) + // - __sveltets_2_ensureRightProps needs to be declared in a way that doesn't affect the type result of props return ( '{...__sveltets_2_ensureRightProps<{' + this.createReturnElementsType(lets).join(',') + '}>(__sveltets_2_any("") as $$Props), ' + - '...__sveltets_2_ensureRightProps<' + - (uses$$propsOr$$restProps ? 'Partial<$$Props>' : '$$Props') + - '>({' + - this.createReturnElements(lets, false).join(',') + - '}), ...{} as unknown as $$Props, ...{' + + '...{} as unknown as $$Props, ...{' + // We add other exports of classes and functions here because // they need to appear in the props object in order to properly // type bind:xx but they are not needed to be part of $$Props diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-interface/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-interface/expectedv2.ts index 930dca79c..0d0cebeb4 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-interface/expectedv2.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-interface/expectedv2.ts @@ -31,7 +31,7 @@ ; async () => {}; -return { props: {...__sveltets_2_ensureRightProps<{exported1: string,exported2?: string,name1?: string,name2: string,renamed1?: string,renamed2: string}>(__sveltets_2_any("") as $$Props), ...__sveltets_2_ensureRightProps<$$Props>({exported1: exported1,exported2: exported2,name1: name1,name2: name2,renamed1: rename1,renamed2: rename2}), ...{} as unknown as $$Props, ...{Foo: Foo, bar: bar, baz: baz, RenamedFoo: RenameFoo, renamedbar: renamebar, renamedbaz: renamebaz} as {Foo?: typeof Foo,bar?: typeof bar,baz?: string,RenamedFoo?: typeof RenameFoo,renamedbar?: typeof renamebar,renamedbaz?: string}}, slots: {}, events: {} }} +return { props: {...__sveltets_2_ensureRightProps<{exported1: string,exported2?: string,name1?: string,name2: string,renamed1?: string,renamed2: string}>(__sveltets_2_any("") as $$Props), ...{} as unknown as $$Props, ...{Foo: Foo, bar: bar, baz: baz, RenamedFoo: RenameFoo, renamedbar: renamebar, renamedbaz: renamebaz} as {Foo?: typeof Foo,bar?: typeof bar,baz?: string,RenamedFoo?: typeof RenameFoo,renamedbar?: typeof renamebar,renamedbaz?: string}}, slots: {}, events: {} }} export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_with_any_event(render())) { } \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-type/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-type/expectedv2.ts index 7dbeb2244..df6f73d09 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-type/expectedv2.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-type/expectedv2.ts @@ -31,7 +31,7 @@ ; async () => {}; -return { props: {...__sveltets_2_ensureRightProps<{exported1: string,exported2?: string,name1?: string,name2: string,renamed1?: string,renamed2: string}>(__sveltets_2_any("") as $$Props), ...__sveltets_2_ensureRightProps<$$Props>({exported1: exported1,exported2: exported2,name1: name1,name2: name2,renamed1: rename1,renamed2: rename2}), ...{} as unknown as $$Props, ...{Foo: Foo, bar: bar, baz: baz, RenamedFoo: RenameFoo, renamedbar: renamebar, renamedbaz: renamebaz} as {Foo?: typeof Foo,bar?: typeof bar,baz?: string,RenamedFoo?: typeof RenameFoo,renamedbar?: typeof renamebar,renamedbaz?: string}}, slots: {}, events: {} }} +return { props: {...__sveltets_2_ensureRightProps<{exported1: string,exported2?: string,name1?: string,name2: string,renamed1?: string,renamed2: string}>(__sveltets_2_any("") as $$Props), ...{} as unknown as $$Props, ...{Foo: Foo, bar: bar, baz: baz, RenamedFoo: RenameFoo, renamedbar: renamebar, renamedbaz: renamebaz} as {Foo?: typeof Foo,bar?: typeof bar,baz?: string,RenamedFoo?: typeof RenameFoo,renamedbar?: typeof renamebar,renamedbaz?: string}}, slots: {}, events: {} }} export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_with_any_event(render())) { } \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-with-$$props/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-with-$$props/expectedv2.ts index 9a409bef3..33b0fa0c7 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-with-$$props/expectedv2.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-with-$$props/expectedv2.ts @@ -13,7 +13,7 @@ async () => { $$props;}; -return { props: {...__sveltets_2_ensureRightProps<{}>(__sveltets_2_any("") as $$Props), ...__sveltets_2_ensureRightProps>({}), ...{} as unknown as $$Props, ...{c: c} as {c?: typeof c}}, slots: {}, events: {} }} +return { props: {...__sveltets_2_ensureRightProps<{}>(__sveltets_2_any("") as $$Props), ...{} as unknown as $$Props, ...{c: c} as {c?: typeof c}}, slots: {}, events: {} }} export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_with_any_event(render())) { get c() { return __sveltets_2_nonNullable(this.$$prop_def.c) } From fba03df1a347868a92d55ee026cdfe4e89f8ab9f Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Fri, 10 Mar 2023 15:13:08 +0100 Subject: [PATCH 2/2] fix --- .../diagnostics/fixtures/$$props-invalid3/expectedv2.json | 8 -------- 1 file changed, 8 deletions(-) diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/$$props-invalid3/expectedv2.json b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/$$props-invalid3/expectedv2.json index 976a9a1f1..2fd99dabb 100644 --- a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/$$props-invalid3/expectedv2.json +++ b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/$$props-invalid3/expectedv2.json @@ -6,13 +6,5 @@ "message": "Argument of type '$$Props' is not assignable to parameter of type '{ wrong: boolean; }'.\n Property 'wrong' is missing in type '$$Props' but required in type '{ wrong: boolean; }'.", "code": 2345, "tags": [] - }, - { - "range": { "start": { "line": 1, "character": 11 }, "end": { "line": 1, "character": 18 } }, - "severity": 1, - "source": "ts", - "message": "Argument of type '{ wrong: boolean; }' is not assignable to parameter of type '$$Props'.\n Object literal may only specify known properties, and 'wrong' does not exist in type '$$Props'.", - "code": 2345, - "tags": [] } ]