Skip to content

Commit 4660a4c

Browse files
authored
(fix) don't widen props type when using $$props while using $$Props (#1268)
1 parent 1b1c3fd commit 4660a4c

File tree

9 files changed

+84
-22
lines changed

9 files changed

+84
-22
lines changed

packages/svelte2tsx/src/svelte2tsx/addComponentExport.ts

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { Generics } from './nodes/Generics';
77

88
export interface AddComponentExportPara {
99
str: MagicString;
10-
uses$$propsOr$$restProps: boolean;
10+
canHaveAnyProp: boolean;
1111
/**
1212
* If true, not fallback to `any`
1313
* -> all unknown events will throw a type error
@@ -38,7 +38,7 @@ export function addComponentExport(params: AddComponentExportPara) {
3838

3939
function addGenericsComponentExport({
4040
strictEvents,
41-
uses$$propsOr$$restProps,
41+
canHaveAnyProp,
4242
exportedNames,
4343
componentDocumentation,
4444
fileName,
@@ -60,12 +60,7 @@ function addGenericsComponentExport({
6060
let statement = `
6161
class __sveltets_Render${genericsDef} {
6262
props() {
63-
return ${props(
64-
true,
65-
uses$$propsOr$$restProps,
66-
exportedNames,
67-
`render${genericsRef}()`
68-
)}.props;
63+
return ${props(true, canHaveAnyProp, exportedNames, `render${genericsRef}()`)}.props;
6964
}
7065
events() {
7166
return ${events(strictEvents, `render${genericsRef}()`)}.events;
@@ -105,7 +100,7 @@ class __sveltets_Render${genericsDef} {
105100
function addSimpleComponentExport({
106101
strictEvents,
107102
isTsFile,
108-
uses$$propsOr$$restProps,
103+
canHaveAnyProp,
109104
exportedNames,
110105
componentDocumentation,
111106
fileName,
@@ -115,7 +110,7 @@ function addSimpleComponentExport({
115110
}: AddComponentExportPara) {
116111
const propDef = props(
117112
isTsFile,
118-
uses$$propsOr$$restProps,
113+
canHaveAnyProp,
119114
exportedNames,
120115
events(strictEvents, 'render()')
121116
);
@@ -167,15 +162,15 @@ function events(strictEvents: boolean, renderStr: string) {
167162

168163
function props(
169164
isTsFile: boolean,
170-
uses$$propsOr$$restProps: boolean,
165+
canHaveAnyProp: boolean,
171166
exportedNames: ExportedNames,
172167
renderStr: string
173168
) {
174169
if (isTsFile) {
175-
return uses$$propsOr$$restProps ? `__sveltets_1_with_any(${renderStr})` : renderStr;
170+
return canHaveAnyProp ? `__sveltets_1_with_any(${renderStr})` : renderStr;
176171
} else {
177172
const optionalProps = exportedNames.createOptionalPropsArray();
178-
const partial = `__sveltets_1_partial${uses$$propsOr$$restProps ? '_with_any' : ''}`;
173+
const partial = `__sveltets_1_partial${canHaveAnyProp ? '_with_any' : ''}`;
179174
return optionalProps.length > 0
180175
? `${partial}([${optionalProps.join(',')}], ${renderStr})`
181176
: `${partial}(${renderStr})`;

packages/svelte2tsx/src/svelte2tsx/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ export function svelte2tsx(
382382

383383
addComponentExport({
384384
str,
385-
uses$$propsOr$$restProps: uses$$props || uses$$restProps,
385+
canHaveAnyProp: !exportedNames.uses$$Props && (uses$$props || uses$$restProps),
386386
strictEvents: events.hasStrictEvents(),
387387
isTsFile: options?.isTsFile,
388388
exportedNames,

packages/svelte2tsx/src/svelte2tsx/nodes/ExportedNames.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ interface ExportedName {
1717
}
1818

1919
export class ExportedNames {
20-
private uses$$Props = false;
20+
public uses$$Props = false;
2121
private exports = new Map<string, ExportedName>();
2222
private possibleExports = new Map<
2323
string,
@@ -210,10 +210,6 @@ export class ExportedNames {
210210
.join('');
211211
}
212212

213-
setUses$$Props(): void {
214-
this.uses$$Props = true;
215-
}
216-
217213
/**
218214
* Marks a top level declaration as a possible export
219215
* which could be exported through `export { .. }` later.
@@ -332,6 +328,9 @@ export class ExportedNames {
332328
'...__sveltets_1_ensureRightProps<Partial<$$Props>>({' +
333329
this.createReturnElements(lets, false).join(',') +
334330
'}), ...{} as unknown as $$Props, ...{' +
331+
// We add other exports of classes and functions here because
332+
// they need to appear in the props object in order to properly
333+
// type bind:xx but they are not needed to be part of $$Props
335334
this.createReturnElements(others, false).join(', ') +
336335
'} as {' +
337336
this.createReturnElementsType(others).join(',') +

packages/svelte2tsx/src/svelte2tsx/processInstanceScriptContent.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ export function processInstanceScriptContent(
250250
uses$$SlotsInterface = true;
251251
}
252252
if (is$$PropsDeclaration(node)) {
253-
exportedNames.setUses$$Props();
253+
exportedNames.uses$$Props = true;
254254
}
255255

256256
if (ts.isVariableStatement(node)) {

packages/svelte2tsx/test/emitDts/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,12 @@ async function testEmitDts(sample: string) {
3737
true,
3838
`Did not expect file or folder ${file}`
3939
);
40-
const expectedContent = fs.readFileSync(join(cwd, 'expected', file), 'utf-8');
41-
const actualContent = fs.readFileSync(join(cwd, 'package', file), 'utf-8');
40+
const expectedContent = fs
41+
.readFileSync(join(cwd, 'expected', file), 'utf-8')
42+
.replace(/\r\n/g, '\n');
43+
const actualContent = fs
44+
.readFileSync(join(cwd, 'package', file), 'utf-8')
45+
.replace(/\r\n/g, '\n');
4246
assert.strictEqual(
4347
actualContent,
4448
expectedContent,
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { SvelteComponentTyped } from "svelte";
2+
declare const __propDef: {
3+
props: {
4+
b?: () => void;
5+
/**
6+
* comment is preserved
7+
*/
8+
a: string;
9+
};
10+
events: {
11+
[evt: string]: CustomEvent<any>;
12+
};
13+
slots: {};
14+
};
15+
export declare type Test3PropsProps = typeof __propDef.props;
16+
export declare type Test3PropsEvents = typeof __propDef.events;
17+
export declare type Test3PropsSlots = typeof __propDef.slots;
18+
export default class Test3Props extends SvelteComponentTyped<Test3PropsProps, Test3PropsEvents, Test3PropsSlots> {
19+
get b(): () => void;
20+
}
21+
export {};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<script lang="ts">
2+
interface $$Props {
3+
/**
4+
* comment is preserved
5+
*/
6+
a: string;
7+
}
8+
export function b() {}
9+
</script>
10+
11+
{$$props}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
///<reference types="svelte" />
2+
<></>;function render() { let $$props = __sveltets_1_allPropsType();
3+
4+
interface $$Props {
5+
/**
6+
* comment
7+
*/
8+
a: boolean;
9+
b?: string;
10+
}
11+
function c() {}
12+
;
13+
() => (<>
14+
15+
{$$props}</>);
16+
return { props: {...__sveltets_1_ensureRightProps<{}>(__sveltets_1_any("") as $$Props), ...__sveltets_1_ensureRightProps<Partial<$$Props>>({}), ...{} as unknown as $$Props, ...{c: c} as {c?: typeof c}}, slots: {}, getters: {c: c}, events: {} }}
17+
18+
export default class Input__SvelteComponent_ extends __sveltets_1_createSvelte2TsxComponent(__sveltets_1_with_any_event(render())) {
19+
get c() { return render().getters.c }
20+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<script lang="ts">
2+
interface $$Props {
3+
/**
4+
* comment
5+
*/
6+
a: boolean;
7+
b?: string;
8+
}
9+
export function c() {}
10+
</script>
11+
<!-- using $$props while using $$Props shouldn't widen the props type allow any prop -->
12+
{$$props}

0 commit comments

Comments
 (0)