Vue 3自定义v-model辅助函数类型定义报错问题求助
类型问题修复方案
报错原因
原有定义中props: Record<string, T>要求所有字符串键对应的值均为T类型,但Vue会自动向props注入所有onXxx格式的事件属性,固定为undefined类型,和你的泛型T产生索引签名冲突,因此触发报错。
修正后完整代码
import { computed, SetupContext, WritableComputedRef } from 'vue'; export const vModel = < P extends object, K extends keyof P = 'modelValue' >( props: P, context: SetupContext, binding: K = 'modelValue' as K ): WritableComputedRef<P[K]> => { return computed({ get: () => props[binding], set: (value: P[K]) => { context.emit(`update:${binding as string}`, value); } }) }
核心修改说明
- 新增泛型
P extends object适配任意组件的props类型,放弃要求全量索引签名,避免和Vue注入的事件属性冲突 - 新增泛型
K extends keyof P约束绑定的键名必须是props中显式定义的属性,天然过滤Vue自动注入的on${string}类特殊属性 - 泛型K默认值设为
modelValue,兼容不传绑定名的默认使用场景 - 返回值自动推导为对应绑定属性的类型,无需手动传入泛型参数,类型安全性更高
使用示例
<script setup lang="ts"> const props = defineProps<{ modelValue: string count: number }>() const emit = defineEmits<{ 'update:modelValue': [value: string] 'update:count': [value: number] }>() // 默认绑定modelValue,自动推导为WritableComputedRef<string> const value = vModel(props, emit) // 绑定count属性,自动推导为WritableComputedRef<number> const currentCount = vModel(props, emit, 'count') </script>
内容的提问来源于stack exchange,提问作者Fex
相关产品推荐
相关产品推荐

