Skip to content
This repository was archived by the owner on Jul 19, 2025. It is now read-only.

Commit 8492c3c

Browse files
committed
fix(compiler-sfc): preserve old behavior when using withDefaults with desutructure
close #11930
1 parent fbae210 commit 8492c3c

File tree

3 files changed

+43
-21
lines changed

3 files changed

+43
-21
lines changed

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -378,14 +378,15 @@ describe('sfc reactive props destructure', () => {
378378
).toThrow(`destructure cannot use computed key`)
379379
})
380380

381-
test('should error when used with withDefaults', () => {
382-
expect(() =>
383-
compile(
384-
`<script setup lang="ts">
385-
const { foo } = withDefaults(defineProps<{ foo: string }>(), { foo: 'foo' })
386-
</script>`,
387-
),
388-
).toThrow(`withDefaults() is unnecessary when using destructure`)
381+
test('should warn when used with withDefaults', () => {
382+
compile(
383+
`<script setup lang="ts">
384+
const { foo } = withDefaults(defineProps<{ foo: string }>(), { foo: 'foo' })
385+
</script>`,
386+
)
387+
expect(
388+
`withDefaults() is unnecessary when using destructure`,
389+
).toHaveBeenWarned()
389390
})
390391

391392
test('should error if destructure reference local vars', () => {

packages/compiler-sfc/src/script/context.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type { ModelDecl } from './defineModel'
88
import type { BindingMetadata } from '../../../compiler-core/src'
99
import MagicString from 'magic-string'
1010
import type { TypeScope } from './resolveType'
11+
import { warn } from '../warn'
1112

1213
export class ScriptCompileContext {
1314
isJS: boolean
@@ -145,20 +146,31 @@ export class ScriptCompileContext {
145146
return block.content.slice(node.start!, node.end!)
146147
}
147148

149+
warn(msg: string, node: Node, scope?: TypeScope): void {
150+
warn(generateError(msg, node, this, scope))
151+
}
152+
148153
error(msg: string, node: Node, scope?: TypeScope): never {
149-
const offset = scope ? scope.offset : this.startOffset!
150154
throw new Error(
151-
`[@vue/compiler-sfc] ${msg}\n\n${
152-
(scope || this.descriptor).filename
153-
}\n${generateCodeFrame(
154-
(scope || this.descriptor).source,
155-
node.start! + offset,
156-
node.end! + offset,
157-
)}`,
155+
`[@vue/compiler-sfc] ${generateError(msg, node, this, scope)}`,
158156
)
159157
}
160158
}
161159

160+
function generateError(
161+
msg: string,
162+
node: Node,
163+
ctx: ScriptCompileContext,
164+
scope?: TypeScope,
165+
) {
166+
const offset = scope ? scope.offset : ctx.startOffset!
167+
return `${msg}\n\n${(scope || ctx.descriptor).filename}\n${generateCodeFrame(
168+
(scope || ctx.descriptor).source,
169+
node.start! + offset,
170+
node.end! + offset,
171+
)}`
172+
}
173+
162174
export function resolveParserPlugins(
163175
lang: string,
164176
userPlugins?: ParserPlugin[],

packages/compiler-sfc/src/script/defineProps.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export function processDefineProps(
4848
ctx: ScriptCompileContext,
4949
node: Node,
5050
declId?: LVal,
51+
isWithDefaults = false,
5152
): boolean {
5253
if (!isCallOf(node, DEFINE_PROPS)) {
5354
return processWithDefaults(ctx, node, declId)
@@ -81,7 +82,7 @@ export function processDefineProps(
8182
}
8283

8384
// handle props destructure
84-
if (declId && declId.type === 'ObjectPattern') {
85+
if (!isWithDefaults && declId && declId.type === 'ObjectPattern') {
8586
processPropsDestructure(ctx, declId)
8687
}
8788

@@ -99,7 +100,14 @@ function processWithDefaults(
99100
if (!isCallOf(node, WITH_DEFAULTS)) {
100101
return false
101102
}
102-
if (!processDefineProps(ctx, node.arguments[0], declId)) {
103+
if (
104+
!processDefineProps(
105+
ctx,
106+
node.arguments[0],
107+
declId,
108+
true /* isWithDefaults */,
109+
)
110+
) {
103111
ctx.error(
104112
`${WITH_DEFAULTS}' first argument must be a ${DEFINE_PROPS} call.`,
105113
node.arguments[0] || node,
@@ -113,10 +121,11 @@ function processWithDefaults(
113121
node,
114122
)
115123
}
116-
if (ctx.propsDestructureDecl) {
117-
ctx.error(
124+
if (declId && declId.type === 'ObjectPattern') {
125+
ctx.warn(
118126
`${WITH_DEFAULTS}() is unnecessary when using destructure with ${DEFINE_PROPS}().\n` +
119-
`Prefer using destructure default values, e.g. const { foo = 1 } = defineProps(...).`,
127+
`Reactive destructure will be disabled when using withDefaults().\n` +
128+
`Prefer using destructure default values, e.g. const { foo = 1 } = defineProps(...). `,
120129
node.callee,
121130
)
122131
}

0 commit comments

Comments
 (0)