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

TypeScript创建对象数组遇类型错误,求解决方案(附代码)

问题解决:TypeScript中map访问属性报never类型错误

错误原因

你遇到的'property name does not exist on type never'错误,核心是**data的类型被TypeScript推断为never[]**。因为初始化useState([])时未指定泛型类型,TS无法判断数组元素的结构,只能默认元素为never类型,自然不允许访问name属性。

分步解决

1. 给状态指定明确类型

首先定义接口描述API返回的国家数据结构(至少包含你用到的字段):

interface CountryData {
  name: {
    common: string;
  };
  // 其他需要用到的字段可按需添加
}

然后修改useState的初始化代码,添加泛型约束:

const [data, setData] = useState<CountryData[]>([]);

这样TS就能识别data是CountryData类型的数组,map遍历的country也会有正确的类型,访问country.name.common就不会报错了。

2. 修复数组初始化问题

你当前的countryArray仅声明类型但未初始化,直接调用push会导致运行时错误。推荐两种写法:

写法一:初始化后遍历填充

let countryArray: CountryInterface[] = [];
function makeCountryArray() {
  data.forEach(country => {
    countryArray.push({ label: country.name.common, value: country.name.common });
  });
}

写法二:用map直接生成数组(更简洁)

const countryArray = data.map(country => ({
  label: country.name.common,
  value: country.name.common
}));

因为返回的对象结构和CountryInterface完全匹配,TS会自动推断类型,无需额外断言。

3. interface和type的选择

在这个场景下,用interface完全合理,type也能实现同样效果,两者在对象类型定义上功能重叠:

  • interface更适合对象类型的定义,支持声明合并(多次定义同一interface会自动合并属性)。
  • type更灵活,可定义联合类型、元组等,也能定义对象类型。
    你当前的用法没问题,不用刻意替换,按个人习惯选择即可。

4. 异步请求的类型约束

为了让TS更准确地推断响应数据类型,建议给axios.get添加泛型:

function getCountries(extraUrl: HomeProps['extra']) {
  axios.get<CountryData[]>(api_url + extraUrl)
    .then((res) => {
      setData(res.data);
    })
    .catch(console.log);
}

这样TS会明确res.data是CountryData[]类型,和setData的参数类型完全匹配。

修改后的完整代码

import axios from 'axios';
import { useEffect, useState } from 'react';
import "./Home.css";

interface HomeProps {
    extra: string
};

interface CountryInterface {
    label: string;
    value: string
};

interface CountryData {
  name: {
    common: string;
  };
}

export default function Home() {
    const api_url =  'https://restcountries.com/v3.1';
    const [data, setData] = useState<CountryData[]>([]);

    function getCountries(extraUrl : HomeProps['extra']) {
        axios.get<CountryData[]>(api_url + extraUrl)
        .then((res) => {
            setData(res.data);
        })
        .catch(console.log);
    };

    useEffect(() => {
        getCountries('/independant?status=true')
    }, []);

    const countryArray = data.map(country => ({
      label: country.name.common,
      value: country.name.common
    }));

    return (
        <div>
            Home
        </div>
    )
}

内容的提问来源于stack exchange,提问作者Papgooner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 17:40:25