Skip to content

Commit 83737b7

Browse files
danielroeTeages
andauthored
fix: keep same behavior with vue in handling Unknown type on defineModel (#37)
Co-authored-by: Teages <[email protected]>
1 parent 0b8a459 commit 83737b7

File tree

2 files changed

+46
-11
lines changed

2 files changed

+46
-11
lines changed

src/utils/script-setup.ts

+18-10
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,21 @@ function processDefineModel(node: Expression, context: Context): string | undefi
171171
return
172172
}
173173

174-
const model = context.utils.inferRuntimeType(context.ctx, modelTypeDecl)
175-
if (!model || model.length === 0 || model[0] === 'Unknown') {
174+
let model = context.utils.inferRuntimeType(context.ctx, modelTypeDecl)
175+
let skipCheck = false
176+
const hasBoolean = model.includes('Boolean')
177+
const hasFunction = model.includes('Function')
178+
const hasUnknownType = model.includes('Unknown')
179+
if (hasUnknownType) {
180+
if (hasBoolean || hasFunction) {
181+
skipCheck = true
182+
model = model.filter(t => t !== 'Unknown')
183+
}
184+
else {
185+
model = ['null']
186+
}
187+
}
188+
if (!model || model.length === 0) {
176189
return
177190
}
178191

@@ -206,20 +219,15 @@ function processDefineModel(node: Expression, context: Context): string | undefi
206219
})
207220
}
208221

209-
node.typeArguments = undefined
210-
node.typeParameters = undefined
211-
node.arguments = modelNameDecl
212-
? [modelNameDecl, modelCodegenDecl]
213-
: [modelCodegenDecl]
214-
215222
const codegenArgs: string[] = []
216223
if (modelNameDecl) {
217224
codegenArgs.push(`"${modelNameDecl.value}"`)
218225
}
219226

220-
const codegenType = model.length === 1 ? model[0] : `[${model.join(',')}]`
227+
const codegenType = model.length === 1 ? model[0] : `[${model.join(', ')}]`
228+
const codegenSkipCheck = skipCheck ? 'skipCheck: true' : ''
221229
const codegenExtra = modelRuntimeDecl ? `...${context.ctx.getString(modelRuntimeDecl)}` : ''
222-
codegenArgs.push(`{ ${[`type: ${codegenType}`, codegenExtra].filter(s => !!s).join(', ')} }`)
230+
codegenArgs.push(`{ ${[`type: ${codegenType}`, codegenSkipCheck, codegenExtra].filter(s => !!s).join(', ')} }`)
223231

224232
return `${DEFINE_MODEL}(${codegenArgs.join(', ')})`
225233
}

test/setup.test.ts

+28-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ describe('transform typescript script setup', () => {
209209
),
210210
).toMatchInlineSnapshot(`
211211
"<script setup>
212-
defineModel("msg", { type: [String,Number,Array] })
212+
defineModel("msg", { type: [String, Number, Array] })
213213
</script>"
214214
`)
215215
expect(
@@ -230,6 +230,33 @@ describe('transform typescript script setup', () => {
230230
defineModel("msg", { type: String, ...{ required: true } })
231231
</script>"
232232
`)
233+
expect(
234+
await fixture(
235+
`<script setup lang="ts">const model = defineModel<number | undefined>()</script>`,
236+
),
237+
).toMatchInlineSnapshot(`
238+
"<script setup>
239+
const model = defineModel({ type: null })
240+
</script>"
241+
`)
242+
expect(
243+
await fixture(
244+
`<script setup lang="ts">const model = defineModel<boolean | undefined>()</script>`,
245+
),
246+
).toMatchInlineSnapshot(`
247+
"<script setup>
248+
const model = defineModel({ type: Boolean, skipCheck: true })
249+
</script>"
250+
`)
251+
expect(
252+
await fixture(
253+
`<script setup lang="ts">const model = defineModel<Function | undefined>()</script>`,
254+
),
255+
).toMatchInlineSnapshot(`
256+
"<script setup>
257+
const model = defineModel({ type: Function, skipCheck: true })
258+
</script>"
259+
`)
233260

234261
await expect(fixture('<script setup lang="ts">defineModel("foo", "bar")</script>')).rejects.toThrow(`[vue-sfc-transformer] defineModel()'s second argument must be an object.`)
235262
})

0 commit comments

Comments
 (0)