core icon indicating copy to clipboard operation
core copied to clipboard

Broken types when using render functions with generic components & defineModel

Open DrWarpMan opened this issue 1 year ago • 6 comments

Vue version

3.5.12

Link to minimal reproduction

https://github.com/DrWarpMan/vue-generic-bug

Steps to reproduce

The bug is described in the comments of the code.

App.vue

<script setup lang="ts">
import { h, ref } from 'vue';
import Comp from './Comp.vue';

const foo = ref<string>('foo');

// val should be of type 'string', not 'unknown'
const FunctionalComponent = () => h(Comp, {
  /* unknown */ modelValue: foo.value, 
  ['onUpdate:modelValue']: (val /* unknown */) => foo.value = val,
});
</script>

<template />

Comp.vue

<script setup lang="ts" generic="T">
defineModel<T>({required: true});
</script>

<template />

What is expected?

Render functions should have proper type based on the provided value to the generic component.

What is actually happening?

Render functions have 'unknown' type, regardless of the provided value to the generic component.

System Info

No response

Any additional comments?

Issue was moved from language-tools repo.

DrWarpMan avatar Nov 01 '24 09:11 DrWarpMan

should be

const FunctionalComponent = () => h(Comp<string>, {
  modelValue: foo.value, 
  ['onUpdate:modelValue']: (val) => foo.value = val,
});

edison1105 avatar Nov 01 '24 14:11 edison1105

So you have to manually specify it, it can't get inferred?

DrWarpMan avatar Nov 01 '24 14:11 DrWarpMan

For generic components, you need to specify the type; there is no way to infer it automatically.

edison1105 avatar Nov 01 '24 14:11 edison1105

Okay, now that I see it, it seems pretty straightforward, but I wonder if this should be mentioned somewhere in the docs?

In any case, the issue can be closed.

DrWarpMan avatar Nov 01 '24 14:11 DrWarpMan

Hello! Looks like this remains an issue with component generics having type parameters default type.

For example, using the given Comp.vue, this should be working and use string as default type param if none is provided, but it is still unknown:

<script setup lang="ts" generic="T = string">
defineModel<T>({required: true});
</script>

<template />

paul-thebaud avatar Nov 27 '25 08:11 paul-thebaud

Is there any new progress on this issue?

YiuYoung avatar Dec 10 '25 03:12 YiuYoung