Skip to content

Commit 25b367f

Browse files
authored
(fix) make uninitialized props be typed as any (#1410)
Also silences "possibly undefined" type errors when using the prop during component initialization
1 parent 9c92206 commit 25b367f

File tree

17 files changed

+75
-50
lines changed

17 files changed

+75
-50
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script lang="ts">
2+
import Component from './untyped-ts.svelte'
3+
</script>
4+
5+
<Component typedAsAny={undefined} untyped={undefined} />
6+
<Component typedAsAny={null} untyped={null} />
7+
<Component typedAsAny={true} untyped={true} />
8+
<Component typedAsAny={123} untyped={123} />
9+
<Component typedAsAny='string' untyped='string' />
10+
<Component typedAsAny={{some: 'object'}} untyped={{some: 'object'}} />
11+
<Component typedAsAny={['string', 'array']} untyped={['string', 'array']} />
12+
<Component typedAsAny={['array', 123, false]} untyped={['array', 123, false]} />
13+
<Component typedAsAny={['array', 123, false]} untyped={['array', 123, false]} />
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<script lang="ts">
2+
export let untyped;
3+
export let typedAsAny: any;
4+
</script>

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

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -112,24 +112,28 @@ export class ExportedNames {
112112
const type = tsType || jsDocType;
113113

114114
if (
115-
!ts.isIdentifier(identifier) ||
116-
(!type &&
115+
ts.isIdentifier(identifier) &&
116+
// Ensure initialization for proper control flow and to avoid "possibly undefined" type errors.
117+
// Also ensure prop is typed as any with a type annotation in TS strict mode
118+
(!declaration.initializer ||
119+
// Widen the type, else it's narrowed to the initializer
120+
type ||
117121
// Edge case: TS infers `export let bla = false` to type `false`.
118122
// prevent that by adding the any-wrap in this case, too.
119-
![ts.SyntaxKind.FalseKeyword, ts.SyntaxKind.TrueKeyword].includes(
120-
declaration.initializer?.kind
121-
))
123+
(!type &&
124+
[ts.SyntaxKind.FalseKeyword, ts.SyntaxKind.TrueKeyword].includes(
125+
declaration.initializer.kind
126+
)))
122127
) {
123-
return;
128+
const name = identifier.getText();
129+
const end = declaration.end + this.astOffset;
130+
131+
preprendStr(
132+
this.str,
133+
end,
134+
surroundWithIgnoreComments(`;${name} = __sveltets_1_any(${name});`)
135+
);
124136
}
125-
const name = identifier.getText();
126-
const end = declaration.end + this.astOffset;
127-
128-
preprendStr(
129-
this.str,
130-
end,
131-
surroundWithIgnoreComments(`;${name} = __sveltets_1_any(${name});`)
132-
);
133137
};
134138

135139
const findComma = (target: ts.Node) =>

packages/svelte2tsx/test/sourcemaps/samples/large-sample-1/mappings.jsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,15 +118,17 @@ s
118118
------------------------------------------------------------------------------------------------------------------------------------------------------ */}
119119
{/**
120120
------------------------------------------------------------------------------------------------------------------------------------------------------ */}
121-
let slug; {/**
122-
╚•let•slug;↲ [generated] line 35
121+
let slug/*Ωignore_startΩ*/;slug = __sveltets_1_any(slug);/*Ωignore_endΩ*/; {/**
122+
╚•let•slug/*Ωignore_startΩ*/;slug•=•__sveltets_1_any(slug);/*Ωignore_endΩ*/; [generated] line 35
123+
╚•let•slug;
123124
•let•slug;
124-
╚export•let•slug;↲ [original] line 29
125+
╚export•let•slug; [original] line 29
125126
------------------------------------------------------------------------------------------------------------------------------------------------------ */}
126-
let chapter; {/**
127-
╚•let•chapter;↲ [generated] line 36
127+
let chapter/*Ωignore_startΩ*/;chapter = __sveltets_1_any(chapter);/*Ωignore_endΩ*/; {/**
128+
╚•let•chapter/*Ωignore_startΩ*/;chapter•=•__sveltets_1_any(chapter);/*Ωignore_endΩ*/; [generated] line 36
129+
╚•let•chapter;
128130
•let•chapter;
129-
╚export•let•chapter;↲ [original] line 30
131+
╚export•let•chapter; [original] line 30
130132
------------------------------------------------------------------------------------------------------------------------------------------------------ */}
131133

132134
const { sections } = getContext('tutorial');

packages/svelte2tsx/test/sourcemaps/samples/reactive-statements/mappings.jsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
1313
<script>↲ [original] line 1 (rest generated at line 2)
1414
------------------------------------------------------------------------------------------------------------------------------------------------------ */}
15-
let prop/*Ωignore_startΩ*/;let $prop = __sveltets_1_store_get(prop);/*Ωignore_endΩ*/ {/**
16-
╚•let•prop/*Ωignore_startΩ*/;let•$prop•=•__sveltets_1_store_get(prop);/*Ωignore_endΩ*/ [generated] line 4
17-
╚•let•prop
18-
•let•prop↲
19-
╚export•let•prop↲ [original] line 2
20-
------------------------------------------------------------------------------------------------------------------------------------------------------ */}
15+
let prop/*Ωignore_startΩ*/;let $prop = __sveltets_1_store_get(prop);/*Ωignore_endΩ*//*Ωignore_startΩ*/;prop = __sveltets_1_any(prop);/*Ωignore_endΩ*/
16+
╚•let•prop/*Ωignore_startΩ*/;let•$prop•=•__sveltets_1_store_get(prop);/*Ωignore_endΩ*//*Ωignore_startΩ*/;prop•=•__sveltets_1_any(prop);/*Ωignore_endΩ*/ [generated] line 4
17+
╚•let•prop
18+
•let•prop↲
19+
╚export•let•prop↲ [original] line 2
20+
//----------------------------------------------------------------------------------------------------------------------------------------------------
2121
let foo = __sveltets_1_invalidate(() => prop); {/**
2222
╚let••foo•=•__sveltets_1_invalidate(()•=>•prop);↲ [generated] line 5
2323
╚ •foo•=• prop; ↲

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,23 @@
44
/**
55
* DOCS!
66
*/
7-
let a;
7+
let a/*Ωignore_startΩ*/;a = __sveltets_1_any(a);/*Ωignore_endΩ*/;
88
/**
99
* not this
1010
*/
1111
/**
1212
* MORE DOCS!
1313
*/
14-
let b;
15-
let c;
14+
let b/*Ωignore_startΩ*/;b = __sveltets_1_any(b);/*Ωignore_endΩ*/;
15+
let c/*Ωignore_startΩ*/;c = __sveltets_1_any(c);/*Ωignore_endΩ*/;
1616
/**
1717
* d
1818
*/
19-
let d;let
19+
let d/*Ωignore_startΩ*/;d = __sveltets_1_any(d);/*Ωignore_endΩ*/;let
2020
/**
2121
* e
2222
*/
23-
e;
23+
e/*Ωignore_startΩ*/;e = __sveltets_1_any(e);/*Ωignore_endΩ*/;
2424
;
2525
() => (<></>);
2626
return { props: {

packages/svelte2tsx/test/svelte2tsx/samples/export-doc/expectedv2.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,23 @@
44
/**
55
* DOCS!
66
*/
7-
let a;
7+
let a/*Ωignore_startΩ*/;a = __sveltets_1_any(a);/*Ωignore_endΩ*/;
88
/**
99
* not this
1010
*/
1111
/**
1212
* MORE DOCS!
1313
*/
14-
let b;
15-
let c;
14+
let b/*Ωignore_startΩ*/;b = __sveltets_1_any(b);/*Ωignore_endΩ*/;
15+
let c/*Ωignore_startΩ*/;c = __sveltets_1_any(c);/*Ωignore_endΩ*/;
1616
/**
1717
* d
1818
*/
19-
let d;let
19+
let d/*Ωignore_startΩ*/;d = __sveltets_1_any(d);/*Ωignore_endΩ*/;let
2020
/**
2121
* e
2222
*/
23-
e;
23+
e/*Ωignore_startΩ*/;e = __sveltets_1_any(e);/*Ωignore_endΩ*/;
2424
;
2525
async () => {};
2626
return { props: {

packages/svelte2tsx/test/svelte2tsx/samples/export-js-required-props/expected.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
///<reference types="svelte" />
22
<></>;function render() {
33

4-
let a;
5-
let b;
4+
let a/*Ωignore_startΩ*/;a = __sveltets_1_any(a);/*Ωignore_endΩ*/;
5+
let b/*Ωignore_startΩ*/;b = __sveltets_1_any(b);/*Ωignore_endΩ*/;
66
let c = 123;
77
;
88
() => (<></>);

0 commit comments

Comments
 (0)