Skip to content

Commit

Permalink
fix(compiler-sfc): fix defineModel coercion for boolean + string unio…
Browse files Browse the repository at this point in the history
…n types (#9603)

close #9587 
close #10676
  • Loading branch information
yangxiuxiu1115 committed Apr 15, 2024
1 parent 67722ba commit 0cef65c
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 7 deletions.
Expand Up @@ -103,6 +103,26 @@ return { modelValue }
})"
`;

exports[`defineModel() > w/ Boolean And Function types, production mode 1`] = `
"import { useModel as _useModel, defineComponent as _defineComponent } from 'vue'
export default /*#__PURE__*/_defineComponent({
props: {
"modelValue": { type: [Boolean, String] },
"modelModifiers": {},
},
emits: ["update:modelValue"],
setup(__props, { expose: __expose }) {
__expose();
const modelValue = _useModel<boolean | string>(__props, "modelValue")
return { modelValue }
}
})"
`;

exports[`defineModel() > w/ array props 1`] = `
"import { useModel as _useModel, mergeModels as _mergeModels } from 'vue'
Expand Down
20 changes: 20 additions & 0 deletions packages/compiler-sfc/__tests__/compileScript/defineModel.spec.ts
Expand Up @@ -221,4 +221,24 @@ describe('defineModel()', () => {
assertCode(content)
expect(content).toMatch(`set: (v) => { return v + __props.x }`)
})

test('w/ Boolean And Function types, production mode', () => {
const { content, bindings } = compile(
`
<script setup lang="ts">
const modelValue = defineModel<boolean | string>()
</script>
`,
{ isProd: true },
)
assertCode(content)
expect(content).toMatch('"modelValue": { type: [Boolean, String] }')
expect(content).toMatch('emits: ["update:modelValue"]')
expect(content).toMatch(
`const modelValue = _useModel<boolean | string>(__props, "modelValue")`,
)
expect(bindings).toStrictEqual({
modelValue: BindingTypes.SETUP_REF,
})
})
})
18 changes: 11 additions & 7 deletions packages/compiler-sfc/src/script/defineModel.ts
Expand Up @@ -129,15 +129,19 @@ export function genModelProps(ctx: ScriptCompileContext) {

let runtimeTypes = type && inferRuntimeType(ctx, type)
if (runtimeTypes) {
const hasBoolean = runtimeTypes.includes('Boolean')
const hasUnknownType = runtimeTypes.includes(UNKNOWN_TYPE)

runtimeTypes = runtimeTypes.filter(el => {
if (el === UNKNOWN_TYPE) return false
return isProd
? el === 'Boolean' || (el === 'Function' && options)
: true
})
skipCheck = !isProd && hasUnknownType && runtimeTypes.length > 0
if (isProd || hasUnknownType) {
runtimeTypes = runtimeTypes.filter(
t =>
t === 'Boolean' ||
(hasBoolean && t === 'String') ||
(t === 'Function' && options),
)

skipCheck = !isProd && hasUnknownType && runtimeTypes.length > 0
}
}

let runtimeType =
Expand Down

0 comments on commit 0cef65c

Please sign in to comment.