Skip to content

Commit 005667f

Browse files
webfansplzyyx990803
authored andcommitted
fix(compiler-sfc): props type should not be optional when setup default value
1 parent 305883a commit 005667f

File tree

3 files changed

+50
-5
lines changed

3 files changed

+50
-5
lines changed

packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,11 +1037,13 @@ import { defaults } from './foo'
10371037
export default /*#__PURE__*/_defineComponent({
10381038
props: _mergeDefaults({
10391039
foo: { type: String, required: false },
1040-
bar: { type: Number, required: false }
1040+
bar: { type: Number, required: false },
1041+
baz: { type: Boolean, required: true }
10411042
}, { ...defaults }) as unknown as undefined,
10421043
setup(__props: {
10431044
foo?: string
10441045
bar?: number
1046+
baz: boolean
10451047
}, { expose }) {
10461048
expose()
10471049
@@ -1060,11 +1062,13 @@ exports[`SFC compile <script setup> with TypeScript withDefaults (static) 1`] =
10601062
export default /*#__PURE__*/_defineComponent({
10611063
props: {
10621064
foo: { type: String, required: false, default: 'hi' },
1063-
bar: { type: Number, required: false }
1065+
bar: { type: Number, required: false },
1066+
baz: { type: Boolean, required: true }
10641067
} as unknown as undefined,
10651068
setup(__props: {
1066-
foo?: string
1069+
foo: string
10671070
bar?: number
1071+
baz: boolean
10681072
}, { expose }) {
10691073
expose()
10701074

packages/compiler-sfc/__tests__/compileScript.spec.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,7 @@ const emit = defineEmits(['a', 'b'])
800800
const props = withDefaults(defineProps<{
801801
foo?: string
802802
bar?: number
803+
baz: boolean
803804
}>(), {
804805
foo: 'hi'
805806
})
@@ -810,10 +811,17 @@ const emit = defineEmits(['a', 'b'])
810811
`foo: { type: String, required: false, default: 'hi' }`
811812
)
812813
expect(content).toMatch(`bar: { type: Number, required: false }`)
814+
expect(content).toMatch(`baz: { type: Boolean, required: true }`)
815+
expect(content).toMatch(`{
816+
foo: string
817+
bar?: number
818+
baz: boolean
819+
}`)
813820
expect(content).toMatch(`const props = __props`)
814821
expect(bindings).toStrictEqual({
815822
foo: BindingTypes.PROPS,
816823
bar: BindingTypes.PROPS,
824+
baz: BindingTypes.PROPS,
817825
props: BindingTypes.SETUP_CONST
818826
})
819827
})
@@ -825,6 +833,7 @@ const emit = defineEmits(['a', 'b'])
825833
const props = withDefaults(defineProps<{
826834
foo?: string
827835
bar?: number
836+
baz: boolean
828837
}>(), { ...defaults })
829838
</script>
830839
`)
@@ -834,7 +843,8 @@ const emit = defineEmits(['a', 'b'])
834843
`
835844
_mergeDefaults({
836845
foo: { type: String, required: false },
837-
bar: { type: Number, required: false }
846+
bar: { type: Number, required: false },
847+
baz: { type: Boolean, required: true }
838848
}, { ...defaults })`.trim()
839849
)
840850
})

packages/compiler-sfc/src/compileScript.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,36 @@ export function compileScript(
572572
return `\n props: ${propsDecls} as unknown as undefined,`
573573
}
574574

575+
function genSetupPropsArgs(
576+
props: Record<string, PropTypeData>,
577+
propsArgs: string
578+
) {
579+
const keys = Object.keys(props)
580+
if (!keys.length) {
581+
return ``
582+
}
583+
const hasStaticDefaults =
584+
propsRuntimeDefaults &&
585+
propsRuntimeDefaults.type === 'ObjectExpression' &&
586+
propsRuntimeDefaults.properties.every(
587+
node => node.type === 'ObjectProperty' && !node.computed
588+
)
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+
propsArgs = propsArgs.replace(`${key}?`, key)
598+
}
599+
}
600+
}
601+
})
602+
return `: ${propsArgs}`
603+
}
604+
575605
// 1. process normal <script> first if it exists
576606
let scriptAst
577607
if (script) {
@@ -990,10 +1020,11 @@ export function compileScript(
9901020
// 9. finalize setup() argument signature
9911021
let args = `__props`
9921022
if (propsTypeDecl) {
993-
args += `: ${scriptSetup.content.slice(
1023+
const propsArgs = `${scriptSetup.content.slice(
9941024
propsTypeDecl.start!,
9951025
propsTypeDecl.end!
9961026
)}`
1027+
args += genSetupPropsArgs(typeDeclaredProps, propsArgs)
9971028
}
9981029
// inject user assignment of props
9991030
// we use a default __props so that template expressions referencing props

0 commit comments

Comments
 (0)