如何在单个v-for循环中使用不同类型列表且通过TypeScript类型检查?
解决TypeScript类型不匹配的可行方案
方案1:类型断言明确分支类型
直接在循环数据源处通过类型断言告知TS当前分支的明确类型,消除类型歧义:
<template> <div v-for="(item, index) in (openTab === 1 ? state.articleTypeList : Object.values(state.renderPriceClassNameList))" :key="index" > <span v-if="openTab === 1">{{ item }}</span> <div v-else v-for="subItem in (item as string[])" :key="subItem"> {{ subItem }} </div> </div> </template> <script setup lang="ts"> import { reactive, ref } from 'vue' const state = reactive({ articleTypeList: ['资讯', '教程'], renderPriceClassNameList: { 低价区: ['9.9元', '19.9元'], 高价区: ['99元', '199元'] } }) const openTab = ref(1) </script>
注意:必须保证openTab的判断逻辑和类型断言的分支完全对应,避免运行时类型错误。
方案2:用计算属性返回精准类型
通过计算属性根据openTab分支返回明确类型的数据源,让TS自动推导正确类型,无需手动断言:
<template> <div v-for="(item, index) in currentDataSource" :key="index"> <span v-if="openTab === 1">{{ item }}</span> <div v-else v-for="subItem in item" :key="subItem"> {{ subItem }} </div> </div> </template> <script setup lang="ts"> import { reactive, ref, computed } from 'vue' const state = reactive({ articleTypeList: ['资讯', '教程'], renderPriceClassNameList: { 低价区: ['9.9元', '19.9元'], 高价区: ['99元', '199元'] } }) const openTab = ref(1) const currentDataSource = computed(() => { if (openTab.value === 1) { return state.articleTypeList // TS自动推导为string[] } else { return Object.values(state.renderPriceClassNameList) // TS自动推导为string[][] } }) </script>
这种方式更安全,计算属性内部的分支判断会让TS精准识别返回类型,避免手动断言的潜在风险。
方案3:自定义类型守卫
针对复杂场景,可编写类型守卫函数让TS在渲染逻辑中自动识别数据类型:
<template> <div v-for="(item, index) in mixedDataSource" :key="index"> <span v-if="isStringItem(item)">{{ item }}</span> <div v-else v-for="subItem in item" :key="subItem"> {{ subItem }} </div> </div> </template> <script setup lang="ts"> import { reactive, ref, computed } from 'vue' const state = reactive({ articleTypeList: ['资讯', '教程'], renderPriceClassNameList: { 低价区: ['9.9元', '19.9元'], 高价区: ['99元', '199元'] } }) const openTab = ref(1) const mixedDataSource = computed(() => { return openTab.value === 1 ? state.articleTypeList : Object.values(state.renderPriceClassNameList) }) // 自定义类型守卫函数 function isStringItem(item: string | string[]): item is string { return typeof item === 'string' } </script>
类型守卫能让TS在渲染逻辑中自动区分item的类型,彻底消除类型错误提示。
内容的提问来源于stack exchange,提问作者Artur Müller Romanov
相关产品推荐
相关产品推荐

