-
-
Notifications
You must be signed in to change notification settings - Fork 8.7k
defineModel ignores TS types #9587
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
I think this is related to special handling for boolean props that we also have in other scenarios. When we define props with a type interface, we generate the prop runtime definition without a runtime type (because the component will provide TS types to devs): const modelValue = defineModel<string | number | null>()
// results in runtime prop def:
props: {
"modelValue": {},
}, But when the prop is of type Boolean, we need to know that during runtime for casting props values properly. const modelValue = defineModel<boolean>()
// results in runtime prop def:
props: {
"modelValue": { type: Boolean },
}, Problem is that we get the same result for a union type containing const modelValue = defineModel<string | number | null | boolean>()
// results in runtime prop def:
props: {
"modelValue": { type: Boolean },
}, It would need to be: const modelValue = defineModel<string | number | null | boolean>()
// results in runtime prop def:
props: {
"modelValue": { type: [Boolean, String, Number] },
}, |
I briefly reviewed the source code and it looks like it was intentionally done. In the product environment, supports Boolean and Function when options are passed in. core/packages/compiler-sfc/src/script/defineModel.ts Lines 123 to 128 in fc79029
|
@RicardoErii core/packages/compiler-sfc/src/script/defineProps.ts Lines 262 to 276 in fc79029
|
Any update on this issue ? I've created a reproduction link (library mode) : https://stackblitz.com/edit/vitejs-vite-zz3d8x?file=dist%2Fmy-lib.js&view=editor and I've noticed a weird case. When typing using TypeScript AND setting <script setup lang="ts">
const a = defineModel<boolean>('a');
const b = defineModel<string>('b');
const c = defineModel<string | boolean>('c');
const d = defineModel<string | boolean>('d', { type: [String, Boolean] });
const e = defineModel('e', {type: [String, Boolean]});
</script> // lib output
import { defineComponent as t, useModel as o } from 'vue';
const n = /* @__PURE__ */ t({
__name: 'SampleComponent',
props: {
a: { type: Boolean },
aModifiers: {},
b: {},
bModifiers: {},
c: { type: Boolean }, // <-- Should be {type: [String, Boolean] }
cModifiers: {},
d: { type: Boolean, type: [String, Boolean] }, // <-- type property is duplicated with different values
dModifiers: {},
e: { type: [String, Boolean] },
eModifiers: {},
},
emits: ['update:a', 'update:b', 'update:c', 'update:d', 'update:e'],
setup(e) {
return o(e, 'a'), o(e, 'b'), o(e, 'c'), o(e, 'd'), o(e, 'e'), () => {};
},
});
export { n as SampleComponent };
//# sourceMappingURL=my-lib.js.map A possible workaround could be to specify type property, but TypeScript complains about it in my editor : |
Any update on this? |
…n types (vuejs#9603) close vuejs#9587 close vuejs#10676
Vue version
3.3.8
Link to minimal reproduction
https://play.vuejs.org/#eNqFUstOwzAQ/JXFlxapNEK9VWklQJUAiYcAwcWXNN2mKY5t+VGKQv6dtUNDQTxO9s7semc9W7MTrYcbj2zMUpubUjuw6LwGkcliwpmznE25LCutjIMaDC6hgaVRFfSorNdRZ6rSLc7ZMAlReJYzLrnMlbQOKlvAJDzQ752jEAqelBGLg94hl2nS9qZOFDistMgcUgSQro6ndR2LmyZNKIpobLc5qtQCBckkmjNIiEuTrpwNSD71XpbFcG2VpBnrUMxZTtWlQHOjXUnaOBtDZAKXkbSXy4g543Gww/MV5s8/4Gu7DRhntwYtmg3N3HEuMwW6lp7dX+OW7h1J2r2g7D/IO7RK+KCxTTv1ckGy9/Ki2otoQSmLBzvbOpR2N1QQGjKbmM8ZORI+7rfRP+WOhqNYx2VDv7hz858l+bA5WPKYCY/k9gKXpcSrAKXWGZIIbyB9NUcTL0LQMVdKYCan/a+b8G0PSqm9A/eqMXSMv7W/AF3XKGV/C5p3e9v5Lg==
Steps to reproduce
Create a Component with a defineModel that got multiple types
Use the component.
Observe warning:
What is expected?
Expected is that the component accepts the string without any errors.
What is actually happening?
The component throws a warning that it got passed a String instead a Boolean
System Info
No response
Any additional comments?
Im now defineModel is an experimental feature , but i guess the user would expect that it works as the usual prop type definition that throws no warning.
The text was updated successfully, but these errors were encountered: