@@ -36,6 +36,7 @@ import {
36
36
CallExpression ,
37
37
RestElement ,
38
38
TSInterfaceBody ,
39
+ TSTypeElement ,
39
40
AwaitExpression ,
40
41
Program ,
41
42
ObjectMethod ,
@@ -558,6 +559,82 @@ export function compileScript(
558
559
return true
559
560
}
560
561
562
+ function getAstBody ( ) : Statement [ ] {
563
+ return scriptAst
564
+ ? [ ...scriptSetupAst . body , ...scriptAst . body ]
565
+ : scriptSetupAst . body
566
+ }
567
+
568
+ function resolveExtendsType (
569
+ node : Node ,
570
+ qualifier : ( node : Node ) => boolean ,
571
+ cache : Array < Node > = [ ]
572
+ ) : Array < Node > {
573
+ if ( node . type === 'TSInterfaceDeclaration' && node . extends ) {
574
+ node . extends . forEach ( extend => {
575
+ if (
576
+ extend . type === 'TSExpressionWithTypeArguments' &&
577
+ extend . expression . type === 'Identifier'
578
+ ) {
579
+ const body = getAstBody ( )
580
+ for ( const node of body ) {
581
+ const qualified = isQualifiedType (
582
+ node ,
583
+ qualifier ,
584
+ extend . expression . name
585
+ )
586
+ if ( qualified ) {
587
+ cache . push ( qualified )
588
+ resolveExtendsType ( node , qualifier , cache )
589
+ return cache
590
+ }
591
+ }
592
+ }
593
+ } )
594
+ }
595
+ return cache
596
+ }
597
+
598
+ function isQualifiedType (
599
+ node : Node ,
600
+ qualifier : ( node : Node ) => boolean ,
601
+ refName : String
602
+ ) : Node | undefined {
603
+ if ( node . type === 'TSInterfaceDeclaration' && node . id . name === refName ) {
604
+ return node . body
605
+ } else if (
606
+ node . type === 'TSTypeAliasDeclaration' &&
607
+ node . id . name === refName &&
608
+ qualifier ( node . typeAnnotation )
609
+ ) {
610
+ return node . typeAnnotation
611
+ } else if ( node . type === 'ExportNamedDeclaration' && node . declaration ) {
612
+ return isQualifiedType ( node . declaration , qualifier , refName )
613
+ }
614
+ }
615
+
616
+ // filter all extends types to keep the override declaration
617
+ function filterExtendsType ( extendsTypes : Node [ ] , bodies : TSTypeElement [ ] ) {
618
+ extendsTypes . forEach ( extend => {
619
+ const body = ( extend as TSInterfaceBody ) . body
620
+ body . forEach ( newBody => {
621
+ if (
622
+ newBody . type === 'TSPropertySignature' &&
623
+ newBody . key . type === 'Identifier'
624
+ ) {
625
+ const name = newBody . key . name
626
+ const hasOverride = bodies . some (
627
+ seenBody =>
628
+ seenBody . type === 'TSPropertySignature' &&
629
+ seenBody . key . type === 'Identifier' &&
630
+ seenBody . key . name === name
631
+ )
632
+ if ( ! hasOverride ) bodies . push ( newBody )
633
+ }
634
+ } )
635
+ } )
636
+ }
637
+
561
638
function resolveQualifiedType (
562
639
node : Node ,
563
640
qualifier : ( node : Node ) => boolean
@@ -570,28 +647,20 @@ export function compileScript(
570
647
node . typeName . type === 'Identifier'
571
648
) {
572
649
const refName = node . typeName . name
573
- const isQualifiedType = ( node : Node ) : Node | undefined => {
574
- if (
575
- node . type === 'TSInterfaceDeclaration' &&
576
- node . id . name === refName
577
- ) {
578
- return node . body
579
- } else if (
580
- node . type === 'TSTypeAliasDeclaration' &&
581
- node . id . name === refName &&
582
- qualifier ( node . typeAnnotation )
583
- ) {
584
- return node . typeAnnotation
585
- } else if ( node . type === 'ExportNamedDeclaration' && node . declaration ) {
586
- return isQualifiedType ( node . declaration )
587
- }
588
- }
589
- const body = scriptAst
590
- ? [ ...scriptSetupAst . body , ...scriptAst . body ]
591
- : scriptSetupAst . body
650
+ const body = getAstBody ( )
592
651
for ( const node of body ) {
593
- const qualified = isQualifiedType ( node )
652
+ let qualified = isQualifiedType (
653
+ node ,
654
+ qualifier ,
655
+ refName
656
+ ) as TSInterfaceBody
594
657
if ( qualified ) {
658
+ const extendsTypes = resolveExtendsType ( node , qualifier )
659
+ if ( extendsTypes . length ) {
660
+ const bodies : TSTypeElement [ ] = [ ...qualified . body ]
661
+ filterExtendsType ( extendsTypes , bodies )
662
+ qualified . body = bodies
663
+ }
595
664
return qualified
596
665
}
597
666
}
0 commit comments