Skip to content

Commit b5163cd

Browse files
authored
(fix) Optional props (#284)
* Determinate if prop is optional based on whether the variable has an initializer.
1 parent 7fe198b commit b5163cd

File tree

9 files changed

+19
-11
lines changed

9 files changed

+19
-11
lines changed

packages/svelte2tsx/src/svelte2tsx.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ type ExportedNames = Map<
334334
{
335335
type?: string;
336336
identifierText?: string;
337+
required?: boolean;
337338
}
338339
>;
339340

@@ -354,7 +355,7 @@ function processInstanceScriptContent(str: MagicString, script: Node): InstanceS
354355
ts.ScriptKind.TS,
355356
);
356357
const astOffset = script.content.start;
357-
const exportedNames = new Map<string, { type?: string; identifierText?: string }>();
358+
const exportedNames: ExportedNames = new Map();
358359

359360
const implicitTopLevelNames: Map<string, number> = new Map();
360361
let uses$$props = false;
@@ -377,6 +378,7 @@ function processInstanceScriptContent(str: MagicString, script: Node): InstanceS
377378
name: ts.BindingName,
378379
target: ts.BindingName = null,
379380
type: ts.TypeNode = null,
381+
required = false,
380382
) => {
381383
if (name.kind != ts.SyntaxKind.Identifier) {
382384
throw Error('export source kind not supported ' + name);
@@ -388,6 +390,7 @@ function processInstanceScriptContent(str: MagicString, script: Node): InstanceS
388390
exportedNames.set(name.text, {
389391
type: type?.getText(),
390392
identifierText: (target as ts.Identifier).text,
393+
required,
391394
});
392395
} else {
393396
exportedNames.set(name.text, {});
@@ -586,9 +589,9 @@ function processInstanceScriptContent(str: MagicString, script: Node): InstanceS
586589
if (ts.isVariableDeclaration(node)) {
587590
if (ts.isIdentifier(node.name)) {
588591
if (node.type) {
589-
addExport(node.name, node.name, node.type);
592+
addExport(node.name, node.name, node.type, !node.initializer);
590593
} else {
591-
addExport(node.name);
594+
addExport(node.name, null, null, !node.initializer);
592595
}
593596
} else if (
594597
ts.isObjectBindingPattern(node.name) ||
@@ -888,8 +891,7 @@ function createPropsStr(exportedNames: ExportedNames) {
888891
return `${identifier}: typeof ${key}`;
889892
}
890893

891-
const containsUndefined = /(^|\s+)undefined(\s+|$)/.test(value.type);
892-
return `${identifier}${containsUndefined ? '?' : ''}: ${value.type}`;
894+
return `${identifier}${value.required ? '' : '?'}: ${value.type}`;
893895
});
894896

895897
return `{${returnElements.join(' , ')}} as {${returnElementsType.join(', ')}}`;
@@ -920,7 +922,7 @@ export function svelte2tsx(svelte: string, options?: { filename?: string; strict
920922
}
921923

922924
//move the instance script and process the content
923-
let exportedNames = new Map<string, { type?: string; identifierText?: string }>();
925+
let exportedNames: ExportedNames = new Map();
924926
if (scriptTag) {
925927
//ensure it is between the module script and the rest of the template (the variables need to be declared before the jsx template)
926928
if (scriptTag.start != instanceScriptTarget) {

packages/svelte2tsx/test/svelte2tsx/samples/export-const/expected.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
const name: string = "world";
44
;
55
<></>
6-
return { props: {name: name} as {name: string}, slots: {} }}
6+
return { props: {name: name} as {name?: string}, slots: {} }}
77

88
export default class {
99
$$prop_def = __sveltets_partial(render().props)

packages/svelte2tsx/test/svelte2tsx/samples/export-has-type/expected.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
interface A {}
44
let a: A;
5+
let b: A = {};b = __sveltets_any(b);;
56
;
67
<></>
7-
return { props: {a: a} as {a: A}, slots: {} }}
8+
return { props: {a: a , b: b} as {a: A, b?: A}, slots: {} }}
89

910
export default class {
1011
$$prop_def = __sveltets_partial(render().props)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script>
22
interface A {}
33
export let a: A;
4+
export let b: A = {};
45
</script>

packages/svelte2tsx/test/svelte2tsx/samples/export-js-strictMode/expected.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
let a: number;
44
let b: number | undefined;
5+
let c: number = 123;c = __sveltets_any(c);;
56
;
67
<></>
7-
return { props: {a: a , b: b} as {a: number, b?: number | undefined}, slots: {} }}
8+
return { props: {a: a , b: b , c: c} as {a: number, b: number | undefined, c?: number}, slots: {} }}
89

910
export default class {
1011
$$prop_def = __sveltets_partial(render().props)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script>
22
export let a: number;
33
export let b: number | undefined;
4+
export let c: number = 123;
45
</script>

packages/svelte2tsx/test/svelte2tsx/samples/export-ts-strictMode/expected.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
let a: number;
44
let b: number | undefined;
5+
let c: number = 123;c = __sveltets_any(c);;
56
;
67
<></>
7-
return { props: {a: a , b: b} as {a: number, b?: number | undefined}, slots: {} }}
8+
return { props: {a: a , b: b , c: c} as {a: number, b: number | undefined, c?: number}, slots: {} }}
89

910
export default class {
1011
$$prop_def = render().props
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script lang="ts">
22
export let a: number;
33
export let b: number | undefined;
4+
export let c: number = 123;
45
</script>

packages/svelte2tsx/test/svelte2tsx/samples/typed-export-with-default/expected.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
let name: string | number = "world";name = __sveltets_any(name);
44
;
55
<></>
6-
return { props: {name: name} as {name: string | number}, slots: {} }}
6+
return { props: {name: name} as {name?: string | number}, slots: {} }}
77

88
export default class {
99
$$prop_def = __sveltets_partial(render().props)

0 commit comments

Comments
 (0)