@@ -38,7 +38,8 @@ import {
38
38
RestElement ,
39
39
TSInterfaceBody ,
40
40
AwaitExpression ,
41
- Program
41
+ Program ,
42
+ ObjectMethod
42
43
} from '@babel/types'
43
44
import { walk } from 'estree-walker'
44
45
import { RawSourceMap } from 'source-map'
@@ -242,7 +243,7 @@ export function compileScript(
242
243
let hasDefineEmitCall = false
243
244
let hasDefineExposeCall = false
244
245
let propsRuntimeDecl : Node | undefined
245
- let propsRuntimeDefaults : Node | undefined
246
+ let propsRuntimeDefaults : ObjectExpression | undefined
246
247
let propsTypeDecl : TSTypeLiteral | TSInterfaceBody | undefined
247
248
let propsTypeDeclRaw : Node | undefined
248
249
let propsIdentifier : string | undefined
@@ -384,7 +385,16 @@ export function compileScript(
384
385
node
385
386
)
386
387
}
387
- propsRuntimeDefaults = node . arguments [ 1 ]
388
+ propsRuntimeDefaults = node . arguments [ 1 ] as ObjectExpression
389
+ if (
390
+ ! propsRuntimeDefaults ||
391
+ propsRuntimeDefaults . type !== 'ObjectExpression'
392
+ ) {
393
+ error (
394
+ `The 2nd argument of ${ WITH_DEFAULTS } must be an object literal.` ,
395
+ propsRuntimeDefaults || node
396
+ )
397
+ }
388
398
} else {
389
399
error (
390
400
`${ WITH_DEFAULTS } ' first argument must be a ${ DEFINE_PROPS } call.` ,
@@ -523,7 +533,9 @@ export function compileScript(
523
533
propsRuntimeDefaults &&
524
534
propsRuntimeDefaults . type === 'ObjectExpression' &&
525
535
propsRuntimeDefaults . properties . every (
526
- node => node . type === 'ObjectProperty' && ! node . computed
536
+ node =>
537
+ ( node . type === 'ObjectProperty' && ! node . computed ) ||
538
+ node . type === 'ObjectMethod'
527
539
)
528
540
)
529
541
}
@@ -534,22 +546,28 @@ export function compileScript(
534
546
return ``
535
547
}
536
548
const hasStaticDefaults = checkStaticDefaults ( )
549
+ const scriptSetupSource = scriptSetup ! . content
537
550
let propsDecls = `{
538
551
${ keys
539
552
. map ( key => {
540
553
let defaultString : string | undefined
541
554
if ( hasStaticDefaults ) {
542
- const prop = (
543
- propsRuntimeDefaults as ObjectExpression
544
- ) . properties . find (
555
+ const prop = propsRuntimeDefaults ! . properties . find (
545
556
( node : any ) => node . key . name === key
546
- ) as ObjectProperty
557
+ ) as ObjectProperty | ObjectMethod
547
558
if ( prop ) {
548
- // prop has corresponding static default value
549
- defaultString = `default: ${ source . slice (
550
- prop . value . start ! + startOffset ,
551
- prop . value . end ! + startOffset
552
- ) } `
559
+ if ( prop . type === 'ObjectProperty' ) {
560
+ // prop has corresponding static default value
561
+ defaultString = `default: ${ scriptSetupSource . slice (
562
+ prop . value . start ! ,
563
+ prop . value . end !
564
+ ) } `
565
+ } else {
566
+ defaultString = `default() ${ scriptSetupSource . slice (
567
+ prop . body . start ! ,
568
+ prop . body . end !
569
+ ) } `
570
+ }
553
571
}
554
572
}
555
573
@@ -577,29 +595,42 @@ export function compileScript(
577
595
return `\n props: ${ propsDecls } as unknown as undefined,`
578
596
}
579
597
580
- function genSetupPropsType (
581
- props : Record < string , PropTypeData > ,
582
- propsType : string
583
- ) {
584
- const keys = Object . keys ( props )
585
- if ( ! keys . length ) {
586
- return ``
587
- }
588
- const hasStaticDefaults = checkStaticDefaults ( )
589
- keys . map ( key => {
590
- if ( hasStaticDefaults ) {
591
- const prop = ( propsRuntimeDefaults as ObjectExpression ) . properties . find (
592
- ( node : any ) => node . key . name === key
593
- ) as ObjectProperty
594
- if ( prop ) {
595
- const { required } = props [ key ]
596
- if ( ! required ) {
597
- propsType = propsType . replace ( `${ key } ?` , key )
598
+ function genSetupPropsType ( node : TSTypeLiteral | TSInterfaceBody ) {
599
+ const scriptSetupSource = scriptSetup ! . content
600
+ if ( checkStaticDefaults ( ) ) {
601
+ // if withDefaults() is used, we need to remove the optional flags
602
+ // on props that have default values
603
+ let res = `: { `
604
+ const members = node . type === 'TSTypeLiteral' ? node . members : node . body
605
+ for ( const m of members ) {
606
+ if (
607
+ ( m . type === 'TSPropertySignature' ||
608
+ m . type === 'TSMethodSignature' ) &&
609
+ m . typeAnnotation &&
610
+ m . key . type === 'Identifier'
611
+ ) {
612
+ if (
613
+ propsRuntimeDefaults ! . properties . some (
614
+ ( p : any ) => p . key . name === ( m . key as Identifier ) . name
615
+ )
616
+ ) {
617
+ res +=
618
+ m . key . name +
619
+ ( m . type === 'TSMethodSignature' ? '()' : '' ) +
620
+ scriptSetupSource . slice (
621
+ m . typeAnnotation . start ! ,
622
+ m . typeAnnotation . end !
623
+ ) +
624
+ ', '
625
+ } else {
626
+ res += scriptSetupSource . slice ( m . start ! , m . end ! ) + `, `
598
627
}
599
628
}
600
629
}
601
- } )
602
- return `: ${ propsType } `
630
+ return ( res . length ? res . slice ( 0 , - 2 ) : res ) + ` }`
631
+ } else {
632
+ return `: ${ scriptSetupSource . slice ( node . start ! , node . end ! ) } `
633
+ }
603
634
}
604
635
605
636
// 1. process normal <script> first if it exists
@@ -1020,11 +1051,7 @@ export function compileScript(
1020
1051
// 9. finalize setup() argument signature
1021
1052
let args = `__props`
1022
1053
if ( propsTypeDecl ) {
1023
- const propsType = `${ scriptSetup . content . slice (
1024
- propsTypeDecl . start ! ,
1025
- propsTypeDecl . end !
1026
- ) } `
1027
- args += genSetupPropsType ( typeDeclaredProps , propsType )
1054
+ args += genSetupPropsType ( propsTypeDecl )
1028
1055
}
1029
1056
// inject user assignment of props
1030
1057
// we use a default __props so that template expressions referencing props
0 commit comments