You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 14:45:47