Skip to content

defineModel() / v-model type mismatch #12216

Closed
@DrWarpMan

Description

@DrWarpMan

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>();

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions