11/** @import { VariableDeclarator, Node, Identifier, AssignmentExpression, LabeledStatement, ExpressionStatement } from 'estree' */
2- /** @import { Visitors } from 'zimmerframe' */
2+ /** @import { Visitors, Context } from 'zimmerframe' */
33/** @import { ComponentAnalysis } from '../phases/types.js' */
44/** @import { Scope, ScopeRoot } from '../phases/scope.js' */
55/** @import { AST, Binding, SvelteNode, ValidatedCompileOptions } from '#compiler' */
@@ -398,6 +398,8 @@ export function migrate(source, { filename, use_ts } = {}) {
398398 }
399399}
400400
401+ /** @typedef {SvelteNode | { type: "TSTypeReference", typeName: Identifier, start: number, end: number } } ASTNode */
402+
401403/**
402404 * @typedef {{
403405 * scope: Scope;
@@ -416,11 +418,12 @@ export function migrate(source, { filename, use_ts } = {}) {
416418 * derived_components: Map<string, string>;
417419 * derived_labeled_statements: Set<LabeledStatement>;
418420 * has_svelte_self: boolean;
421+ * migrate_prop_component_type?: boolean;
419422 * uses_ts: boolean;
420423 * }} State
421424 */
422425
423- /** @type {Visitors<SvelteNode , State> } */
426+ /** @type {Visitors<ASTNode , State> } */
424427const instance_script = {
425428 _ ( node , { state, next } ) {
426429 // @ts -expect-error
@@ -437,8 +440,27 @@ const instance_script = {
437440 }
438441 next ( ) ;
439442 } ,
440- Identifier ( node , { state, path } ) {
443+ TSTypeReference ( node , { state, path } ) {
444+ if ( state . analysis . runes ) return ;
445+ if ( node . typeName . type === 'Identifier' ) {
446+ const binding = state . scope . get ( node . typeName . name ) ;
447+ if (
448+ binding &&
449+ binding . declaration_kind === 'import' &&
450+ binding . initial ?. type === 'ImportDeclaration' &&
451+ binding . initial . source . value ?. toString ( ) . endsWith ( '.svelte' )
452+ ) {
453+ state . str . overwrite (
454+ node . start ,
455+ node . end ,
456+ `import('svelte').ComponentExports<typeof ${ state . str . original . substring ( node . start , node . end ) } >`
457+ ) ;
458+ }
459+ }
460+ } ,
461+ Identifier ( node , { state, path, next } ) {
441462 handle_identifier ( node , state , path ) ;
463+ next ( ) ;
442464 } ,
443465 ImportDeclaration ( node , { state } ) {
444466 state . props_insertion_point = node . end ?? state . props_insertion_point ;
@@ -503,6 +525,8 @@ const instance_script = {
503525 return ;
504526 }
505527
528+ next ( ) ;
529+
506530 let nr_of_props = 0 ;
507531
508532 for ( const declarator of node . declarations ) {
@@ -1409,7 +1433,7 @@ function migrate_slot_usage(node, path, state) {
14091433/**
14101434 * @param {VariableDeclarator } declarator
14111435 * @param {State } state
1412- * @param {SvelteNode [] } path
1436+ * @param {ASTNode [] } path
14131437 */
14141438function extract_type_and_comment ( declarator , state , path ) {
14151439 const str = state . str ;
@@ -1432,7 +1456,10 @@ function extract_type_and_comment(declarator, state, path) {
14321456 while ( str . original [ start ] === ' ' ) {
14331457 start ++ ;
14341458 }
1435- return { type : str . original . substring ( start , declarator . id . typeAnnotation . end ) , comment } ;
1459+ return {
1460+ type : str . snip ( start , declarator . id . typeAnnotation . end ) . toString ( ) ,
1461+ comment
1462+ } ;
14361463 }
14371464
14381465 let cleaned_comment_arr = comment
0 commit comments