Nuxt3/Vue3+TS中v-for报“Property 'name' does not exist on type 'never'”错误解决
错误原因
这是TypeScript的类型推断机制导致的:
- 初始时
state.people被设为空对象{},TS会自动推断它的类型为Record<string, never>(即没有任何属性的空对象类型)。 - 当你在模板中用
v-for遍历state.people时,TS认为遍历出的person是never类型,自然不存在name属性,因此抛出这个linting错误。 - 虽然运行时数据会被正确赋值,但TS在编译阶段无法提前知晓
res.data的结构,所以无法自动更新state.people的类型。
解决方法
以下是几种可行的解决方案,按需选择即可:
方案1:定义明确的接口类型(推荐)
先定义匹配Firebase返回数据结构的接口,再给reactive的状态指定类型,让TS明确知道people的结构:
<template> <div class="pt-4"> <ul> <li v-for="(person, key) in state.people" :key="key"> {{ person.name }} </li> </ul> </div> </template> <script setup lang="ts"> import axios from "axios"; const runtimeConfig = useRuntimeConfig(); // 定义Person接口,可根据实际返回数据添加其他属性 interface Person { name: string; // age: number; 示例其他属性 } // 给state指定类型,people为键是字符串、值是Person的对象 let state = reactive<{ people: Record<string, Person>; }>({ people: {}, }); onMounted(async () => { // 给axios请求也指定返回类型 const res = await axios.get<Record<string, Person>>( `${runtimeConfig.public.firebaseBaseUrl}/people.json` ); state.people = res.data; }); </script>
方案2:使用类型断言快速解决
如果不想定义接口,可以通过类型断言直接告诉TS数据的结构:
<template> <div class="pt-4"> <ul> <li v-for="(person, key) in state.people" :key="key"> {{ person.name }} </li> </ul> </div> </template> <script setup lang="ts"> import axios from "axios"; const runtimeConfig = useRuntimeConfig(); // 给初始空对象断言类型 let state = reactive({ people: {} as Record<string, { name: string }>, }); onMounted(async () => { const res = await axios.get( `${runtimeConfig.public.firebaseBaseUrl}/people.json` ); // 给返回数据也做类型断言 state.people = res.data as Record<string, { name: string }>; }); </script>
方案3:改用ref并指定类型
如果更习惯使用ref管理状态,也可以采用这种方式:
<template> <div class="pt-4"> <ul> <li v-for="(person, key) in people" :key="key"> {{ person.name }} </li> </ul> </div> </template> <script setup lang="ts"> import axios from "axios"; import { ref } from "vue"; const runtimeConfig = useRuntimeConfig(); interface Person { name: string; } // 给ref指定类型,初始值为空对象 const people = ref<Record<string, Person>>({}); onMounted(async () => { const res = await axios.get<Record<string, Person>>( `${runtimeConfig.public.firebaseBaseUrl}/people.json` ); people.value = res.data; }); </script>
关键说明
核心是让TypeScript明确知晓people的数据结构,不管是通过接口定义还是类型断言,只要TS能识别出person拥有name属性,这个linting错误就会消失。推荐使用方案1,因为接口定义能让代码结构更清晰,也方便后续维护。
内容的提问来源于stack exchange,提问作者user20659362
相关产品推荐
相关产品推荐

