Skip to content

Commit fe61944

Browse files
committed
feat(compiler-sfc): support arbitrary expression as withDefaults argument
ref #6459
1 parent 566748c commit fe61944

File tree

3 files changed

+58
-12
lines changed

3 files changed

+58
-12
lines changed

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

+27
Original file line numberDiff line numberDiff line change
@@ -1901,6 +1901,33 @@ const props = __props as {
19011901

19021902

19031903

1904+
return { props, get defaults() { return defaults } }
1905+
}
1906+
1907+
})"
1908+
`;
1909+
1910+
exports[`SFC compile <script setup> > with TypeScript > withDefaults (reference) 1`] = `
1911+
"import { mergeDefaults as _mergeDefaults, defineComponent as _defineComponent } from 'vue'
1912+
import { defaults } from './foo'
1913+
1914+
export default /*#__PURE__*/_defineComponent({
1915+
props: _mergeDefaults({
1916+
foo: { type: String, required: false },
1917+
bar: { type: Number, required: false },
1918+
baz: { type: Boolean, required: true }
1919+
}, defaults),
1920+
setup(__props: any, { expose: __expose }) {
1921+
__expose();
1922+
1923+
const props = __props as {
1924+
foo?: string
1925+
bar?: number
1926+
baz: boolean
1927+
};
1928+
1929+
1930+
19041931
return { props, get defaults() { return defaults } }
19051932
}
19061933

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

+23
Original file line numberDiff line numberDiff line change
@@ -1378,6 +1378,29 @@ const emit = defineEmits(['a', 'b'])
13781378
)
13791379
})
13801380

1381+
test('withDefaults (reference)', () => {
1382+
const { content } = compile(`
1383+
<script setup lang="ts">
1384+
import { defaults } from './foo'
1385+
const props = withDefaults(defineProps<{
1386+
foo?: string
1387+
bar?: number
1388+
baz: boolean
1389+
}>(), defaults)
1390+
</script>
1391+
`)
1392+
assertCode(content)
1393+
expect(content).toMatch(`import { mergeDefaults as _mergeDefaults`)
1394+
expect(content).toMatch(
1395+
`
1396+
_mergeDefaults({
1397+
foo: { type: String, required: false },
1398+
bar: { type: Number, required: false },
1399+
baz: { type: Boolean, required: true }
1400+
}, defaults)`.trim()
1401+
)
1402+
})
1403+
13811404
// #7111
13821405
test('withDefaults (dynamic) w/ production mode', () => {
13831406
const { content } = compile(

packages/compiler-sfc/src/compileScript.ts

+8-12
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ export function compileScript(
313313
let hasDefaultExportRender = false
314314
let hasDefineOptionsCall = false
315315
let propsRuntimeDecl: Node | undefined
316-
let propsRuntimeDefaults: ObjectExpression | undefined
316+
let propsRuntimeDefaults: Node | undefined
317317
let propsDestructureDecl: Node | undefined
318318
let propsDestructureRestId: string | undefined
319319
let propsTypeDecl: PropsDeclType | undefined
@@ -534,15 +534,9 @@ export function compileScript(
534534
node.callee
535535
)
536536
}
537-
propsRuntimeDefaults = node.arguments[1] as ObjectExpression
538-
if (
539-
!propsRuntimeDefaults ||
540-
propsRuntimeDefaults.type !== 'ObjectExpression'
541-
) {
542-
error(
543-
`The 2nd argument of ${WITH_DEFAULTS} must be an object literal.`,
544-
propsRuntimeDefaults || node
545-
)
537+
propsRuntimeDefaults = node.arguments[1]
538+
if (!propsRuntimeDefaults) {
539+
error(`The 2nd argument of ${WITH_DEFAULTS} is required.`, node)
546540
}
547541
} else {
548542
error(
@@ -872,7 +866,9 @@ export function compileScript(
872866
destructured.needSkipFactory ? `, skipFactory: true` : ``
873867
}`
874868
} else if (hasStaticDefaults) {
875-
const prop = propsRuntimeDefaults!.properties.find(node => {
869+
const prop = (
870+
propsRuntimeDefaults as ObjectExpression
871+
).properties.find(node => {
876872
if (node.type === 'SpreadElement') return false
877873
return resolveObjectKey(node.key, node.computed) === key
878874
}) as ObjectProperty | ObjectMethod
@@ -1001,7 +997,7 @@ export function compileScript(
1001997
m.key.type === 'Identifier'
1002998
) {
1003999
if (
1004-
propsRuntimeDefaults!.properties.some(p => {
1000+
(propsRuntimeDefaults as ObjectExpression).properties.some(p => {
10051001
if (p.type === 'SpreadElement') return false
10061002
return (
10071003
resolveObjectKey(p.key, p.computed) ===

0 commit comments

Comments
 (0)