@@ -228,99 +228,101 @@ export class ExportedNames {
228228 return ;
229229 }
230230
231- if ( internalHelpers . isKitRouteFile ( this . basename ) ) {
232- this . $props . mayHaveChildrenProp = this . basename . includes ( 'layout' ) ;
233- const kitType = this . $props . mayHaveChildrenProp
234- ? `{ data: import('./$types.js').LayoutData, form: import('./$types.js').ActionData, children: import('svelte').Snippet }`
235- : `{ data: import('./$types.js').PageData, form: import('./$types.js').ActionData }` ;
236-
237- if ( this . isTsFile ) {
238- this . $props . generic = kitType ;
239- preprendStr (
240- this . str ,
241- node . initializer . expression . end + this . astOffset ,
242- surroundWithIgnoreComments ( `<${ kitType } >` )
243- ) ;
244- } else {
245- this . $props . comment = `/** @type {${ kitType } } */` ;
246- preprendStr ( this . str , node . pos + this . astOffset , this . $props . comment ) ;
247- }
248- } else {
249- // Do a best-effort to extract the props from the object literal
250- let propsStr = '' ;
251- let withUnknown = false ;
252- let props = [ ] ;
253-
254- if ( ts . isObjectBindingPattern ( node . name ) ) {
255- for ( const element of node . name . elements ) {
256- if (
257- ! ts . isIdentifier ( element . name ) ||
258- ( element . propertyName && ! ts . isIdentifier ( element . propertyName ) ) ||
259- ! ! element . dotDotDotToken
260- ) {
261- withUnknown = true ;
262- } else {
263- const name = element . propertyName
264- ? ( element . propertyName as ts . Identifier ) . text
265- : element . name . text ;
266- if ( element . initializer ) {
267- const type = ts . isAsExpression ( element . initializer )
268- ? element . initializer . type . getText ( )
269- : ts . isStringLiteral ( element . initializer )
270- ? 'string'
271- : ts . isNumericLiteral ( element . initializer )
272- ? 'number'
273- : element . initializer . kind === ts . SyntaxKind . TrueKeyword ||
274- element . initializer . kind === ts . SyntaxKind . FalseKeyword
275- ? 'boolean'
276- : ts . isIdentifier ( element . initializer )
277- ? `typeof ${ element . initializer . text } `
278- : 'unknown' ;
279- props . push ( `${ name } ?: ${ type } ` ) ;
280- } else {
281- props . push ( `${ name } : unknown` ) ;
231+ // Do a best-effort to extract the props from the object literal
232+ let propsStr = '' ;
233+ let withUnknown = false ;
234+ let props = [ ] ;
235+
236+ const isKitRouteFile = internalHelpers . isKitRouteFile ( this . basename ) ;
237+ const isKitLayoutFile = isKitRouteFile && this . basename . includes ( 'layout' ) ;
238+ if ( isKitRouteFile ) {
239+ this . $props . mayHaveChildrenProp = isKitLayoutFile ;
240+ }
241+
242+ if ( ts . isObjectBindingPattern ( node . name ) ) {
243+ for ( const element of node . name . elements ) {
244+ if (
245+ ! ts . isIdentifier ( element . name ) ||
246+ ( element . propertyName && ! ts . isIdentifier ( element . propertyName ) ) ||
247+ ! ! element . dotDotDotToken
248+ ) {
249+ withUnknown = true ;
250+ } else {
251+ const name = element . propertyName
252+ ? ( element . propertyName as ts . Identifier ) . text
253+ : element . name . text ;
254+ if ( isKitRouteFile ) {
255+ if ( name === 'data' ) {
256+ props . push (
257+ `data: import('./$types.js').${
258+ isKitLayoutFile ? 'LayoutData' : 'PageData'
259+ } `
260+ ) ;
282261 }
262+ if ( name === 'form' && ! isKitLayoutFile ) {
263+ props . push ( `form: import('./$types.js').ActionData` ) ;
264+ }
265+ } else if ( element . initializer ) {
266+ const type = ts . isAsExpression ( element . initializer )
267+ ? element . initializer . type . getText ( )
268+ : ts . isStringLiteral ( element . initializer )
269+ ? 'string'
270+ : ts . isNumericLiteral ( element . initializer )
271+ ? 'number'
272+ : element . initializer . kind === ts . SyntaxKind . TrueKeyword ||
273+ element . initializer . kind === ts . SyntaxKind . FalseKeyword
274+ ? 'boolean'
275+ : ts . isIdentifier ( element . initializer )
276+ ? `typeof ${ element . initializer . text } `
277+ : 'unknown' ;
278+ props . push ( `${ name } ?: ${ type } ` ) ;
279+ } else {
280+ props . push ( `${ name } : unknown` ) ;
283281 }
284282 }
283+ }
285284
286- if ( props . length > 0 ) {
287- propsStr =
288- `{ ${ props . join ( ', ' ) } }` +
289- ( withUnknown ? ' & Record<string, unknown>' : '' ) ;
290- } else if ( withUnknown ) {
291- propsStr = 'Record<string, unknown>' ;
292- } else {
293- propsStr = 'Record<string, never>' ;
294- }
295- } else {
296- propsStr = 'Record<string, unknown>' ;
285+ if ( isKitLayoutFile ) {
286+ props . push ( `children: import('svelte').Snippet` ) ;
297287 }
298288
299- // Create a virtual type alias for the unnamed generic and reuse it for the props return type
300- // so that rename, find references etc works seamlessly across components
301- if ( this . isTsFile ) {
302- this . $props . generic = '$$_sveltets_Props' ;
303- if ( props . length > 0 || withUnknown ) {
304- preprendStr (
305- this . str ,
306- node . parent . pos + this . astOffset ,
307- surroundWithIgnoreComments ( `;type $$_sveltets_Props = ${ propsStr } ;` )
308- ) ;
309- preprendStr (
310- this . str ,
311- node . initializer . expression . end + this . astOffset ,
312- `<${ this . $props . generic } >`
313- ) ;
314- }
289+ if ( props . length > 0 ) {
290+ propsStr =
291+ `{ ${ props . join ( ', ' ) } }` +
292+ ( withUnknown ? ' & Record<string, unknown>' : '' ) ;
293+ } else if ( withUnknown ) {
294+ propsStr = 'Record<string, unknown>' ;
315295 } else {
316- this . $props . comment = '/** @type {$$_sveltets_Props} */' ;
317- if ( props . length > 0 || withUnknown ) {
318- preprendStr (
319- this . str ,
320- node . pos + this . astOffset ,
321- `/** @typedef {${ propsStr } } $$_sveltets_Props */${ this . $props . comment } `
322- ) ;
323- }
296+ propsStr = 'Record<string, never>' ;
297+ }
298+ } else {
299+ propsStr = 'Record<string, unknown>' ;
300+ }
301+
302+ // Create a virtual type alias for the unnamed generic and reuse it for the props return type
303+ // so that rename, find references etc works seamlessly across components
304+ if ( this . isTsFile ) {
305+ this . $props . generic = '$$_sveltets_Props' ;
306+ if ( props . length > 0 || withUnknown ) {
307+ preprendStr (
308+ this . str ,
309+ node . parent . pos + this . astOffset ,
310+ surroundWithIgnoreComments ( `;type $$_sveltets_Props = ${ propsStr } ;` )
311+ ) ;
312+ preprendStr (
313+ this . str ,
314+ node . initializer . expression . end + this . astOffset ,
315+ `<${ this . $props . generic } >`
316+ ) ;
317+ }
318+ } else {
319+ this . $props . comment = '/** @type {$$_sveltets_Props} */' ;
320+ if ( props . length > 0 || withUnknown ) {
321+ preprendStr (
322+ this . str ,
323+ node . pos + this . astOffset ,
324+ `/** @typedef {${ propsStr } } $$_sveltets_Props */${ this . $props . comment } `
325+ ) ;
324326 }
325327 }
326328 }
0 commit comments