Skip to content

Commit f1872ff

Browse files
committed
fix(compiler-sfc): add error handling for defineModel() without variable assignment
1 parent 163b365 commit f1872ff

File tree

3 files changed

+23
-3
lines changed

3 files changed

+23
-3
lines changed

packages/compiler-core/src/errors.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export enum ErrorCodes {
9090
X_V_MODEL_ON_PROPS,
9191
X_INVALID_EXPRESSION,
9292
X_KEEP_ALIVE_INVALID_CHILDREN,
93-
93+
X_DEFINE_MODEL_NO_VARIABLE,
9494
// generic errors
9595
X_PREFIX_ID_NOT_SUPPORTED,
9696
X_MODULE_MODE_NOT_SUPPORTED,
@@ -179,6 +179,7 @@ export const errorMessages: Record<ErrorCodes, string> = {
179179
[ErrorCodes.X_INVALID_EXPRESSION]: `Error parsing JavaScript expression: `,
180180
[ErrorCodes.X_KEEP_ALIVE_INVALID_CHILDREN]: `<KeepAlive> expects exactly one child component.`,
181181
[ErrorCodes.X_VNODE_HOOKS]: `@vnode-* hooks in templates are no longer supported. Use the vue: prefix instead. For example, @vnode-mounted should be changed to @vue:mounted. @vnode-* hooks support has been removed in 3.4.`,
182+
[ErrorCodes.X_DEFINE_MODEL_NO_VARIABLE]: `defineModel() must be assigned to a variable. For example: const model = defineModel()`,
182183

183184
// generic errors
184185
[ErrorCodes.X_PREFIX_ID_NOT_SUPPORTED]: `"prefixIdentifiers" option is not supported in this build of compiler.`,

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { BindingTypes } from '@vue/compiler-core'
1+
import { BindingTypes, ErrorCodes, errorMessages } from '@vue/compiler-core'
22
import { assertCode, compileSFCScript as compile } from '../utils'
33

44
describe('defineModel()', () => {
@@ -269,4 +269,14 @@ describe('defineModel()', () => {
269269
modelValue: BindingTypes.SETUP_REF,
270270
})
271271
})
272+
273+
test('error when defineModel is not assigned to a variable', () => {
274+
expect(() =>
275+
compile(`
276+
<script setup>
277+
defineModel()
278+
</script>
279+
`),
280+
).toThrow(errorMessages[ErrorCodes.X_DEFINE_MODEL_NO_VARIABLE])
281+
})
272282
})

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ import type { LVal, Node, TSType } from '@babel/types'
22
import type { ScriptCompileContext } from './context'
33
import { inferRuntimeType } from './resolveType'
44
import { UNKNOWN_TYPE, isCallOf, toRuntimeTypeString } from './utils'
5-
import { BindingTypes, unwrapTSNode } from '@vue/compiler-dom'
5+
import {
6+
BindingTypes,
7+
ErrorCodes,
8+
errorMessages,
9+
unwrapTSNode,
10+
} from '@vue/compiler-dom'
611

712
export const DEFINE_MODEL = 'defineModel'
813

@@ -22,6 +27,10 @@ export function processDefineModel(
2227
return false
2328
}
2429

30+
if (!declId) {
31+
ctx.error(errorMessages[ErrorCodes.X_DEFINE_MODEL_NO_VARIABLE], node)
32+
}
33+
2534
ctx.hasDefineModelCall = true
2635

2736
const type =

0 commit comments

Comments
 (0)