Skip to content

defineModel() / v-model type mismatch #12216

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
DrWarpMan opened this issue Oct 18, 2024 · 1 comment · Fixed by vuejs/language-tools#5214 or vuejs/language-tools#5225
Closed

defineModel() / v-model type mismatch #12216

DrWarpMan opened this issue Oct 18, 2024 · 1 comment · Fixed by vuejs/language-tools#5214 or vuejs/language-tools#5225
Labels
language-tools related to vue language-tools scope: types

Comments

@DrWarpMan
Copy link

DrWarpMan commented Oct 18, 2024

Vue version

3.5.12

Link to minimal reproduction

https://play.vuejs.org/#eNqFUk1v1DAQ/SuDLynSbiIoXNp0JUA9gMSHgKMllE0mGxfHtsZ2dqtl/ztjpxs4UHrzzHueeTPzjuKNc+UUUVyJ2rekXACPITrQjdndSBG8FBtp1OgsBTgCYQ8n6MmOUPC34nrB3tnRPQBllYJUNuGtNT5Ab+22IbhJFWofSJnd5qIYUGsLe0u6K54zt65mEdySg4Cj001AjgDq3GBaj7ZDzcrmglJAtYH62XoNSGQJ/GCj7mCLEAayewMDEsJ6zTXqaikoVjwZC+vVrrzz1vD4x9REipa7KI302QXFwqW4gowkrGGx+w85Fyji6pxvB2x//iN/5w8pJ8UXQo80oRQLFhraYZjh22+f8MDvBeQZo2b2f8Cv6K2OSeNMextNx7L/4mW17/NxeNnf/e0hoPHnoZLQxDxlvhR8rLTgx0b/I/eyfJX/SXPiLZ4P/YR/Zg/k07EFOuyVwY8perAC/AITtd5cJBNkWjk1OiKTU/4aqorvqXwqoXqFHlxDaELhsyNnbrBQJHaxgm1cHMefbA/h3iEUc7MCrNH3j5mN/cRz/ZiQ0q54rsvydfnipTj9BpQvD+8=

Steps to reproduce

In the example, you can see a ref that is being passed via v-model to the child component.
The ref's type is string, while the child component's defineModel type is string | null.
The child then modifies the value of the parent's ref to null, which is invalid and should raise an error.

Parent:

<script setup lang="ts">
import { ref } from 'vue';
import Comp from './Comp.vue';
const foobar = ref<string>('hello world');
</script>

<template>
  <Comp v-model="foobar" /> <!-- error should be thrown here -->
</template>

Child:

<script setup lang="ts">
const model = defineModel<string | null>();
model.value = null; // this modifies parent's ref value to 'null', but foobar is of type 'string' only
</script>

<template />

What is expected?

The value that is passed from parent to child via v-model directive, should have equal type to the one that's in the defineModel macro of the child component, otherwise a type error should be thrown.

What is actually happening?

The value passed to the v-model directive can be of any type that "extends" the defineModel type.

System Info

No response

Any additional comments?

This bug happens in cases, where the passed value is a type, that "extends" the defineModel type,
the following also doesn't error:

const foobar = ref<string>('hello world');
// foobar is assignable to this v-model type
const model = defineModel<string | null | undefined | boolean | object | number>();
@patroza
Copy link

patroza commented Mar 1, 2025

@KazariEX neat, but the change breaks type narrowing:

Image

the v-if ensures the swissMarket can't be null

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
language-tools related to vue language-tools scope: types
Projects
None yet
4 participants