Vue 3.3中泛型v-for的key为何出现类型错误?
Vue 3.3.4 泛型列表组件类型错误问题
我基于Vue 3.3.4新增的单文件组件泛型特性,写了一个泛型列表组件——通过props接收items数组,以及用于v-for循环键绑定的itemKey:
<script setup lang="ts" generic="T, K extends keyof T"> defineProps<{ items: Array<T> itemKey: K }>() </script> <template> <ul> <li v-for="item in items" :key="item[itemKey]"> <slot :item="item" /> </li> </ul> </template>
但模板里的:key="item[itemKey]"被标记类型错误,提示内容如下:
Type '[{ type: PropType<K>; required: true; }] extends [Prop<infer V, infer D>] ? unknown extends V ? IfAny<V, V, D> : V : { type: PropType<K>; required: true; }' cannot be used to index type 'T'.
代码本身能正常运行,但类型检查不通过,为什么itemKey会被错误解析?
临时解决方案
用内联的//@ts-ignore跳过类型检查:
<li v-for="(item, i) in items" :key=" //@ts-ignore item[itemKey] " >
问题原因
这是Vue 3.3.x版本中,模板类型推导对泛型props的处理存在的小bug:当在<script setup>中用泛型定义props时,模板里的itemKey没有被正确推导为K extends keyof T的类型,反而被识别成了原始的Prop类型结构,导致TypeScript无法确认它可以作为T的索引键。
更优解决方案
方案1:脚本内定义辅助函数
把索引操作移到<script setup>中,让TypeScript正确推导类型:
<script setup lang="ts" generic="T, K extends keyof T"> const props = defineProps<{ items: Array<T> itemKey: K }>() const getItemKey = (item: T) => item[props.itemKey] </script> <template> <ul> <li v-for="item in items" :key="getItemKey(item)"> <slot :item="item" /> </li> </ul> </template>
方案2:模板内使用类型断言
直接在模板里对itemKey做类型断言:
<template> <ul> <li v-for="item in items" :key="item[itemKey as keyof typeof item]"> <slot :item="item" /> </li> </ul> </template>
方案3:升级Vue版本
这个bug在Vue 3.4及以上版本中已被修复,升级到新版本后,模板会自动正确识别泛型props的类型,无需额外处理。
内容的提问来源于stack exchange,提问作者Soviut
相关产品推荐
相关产品推荐

