React请求URL获取数组数据时报map属性不存在TS错误如何解决
React TypeScript 报错
Property 'map' does not exist on type '{ blocks: never[]; }' 修复方案 问题复现
需求为React项目中请求接口获取块数组数据,接口返回结构如下:
{"data":[ {"id":"3", "type":"blocks", "attributes":{ "index":1, "data":"The Human Torch" }}, {"id":"4", "type":"blocks", "attributes":{ "index":2, "data":"is denied" }}, {"id":"5", "type":"blocks", "attributes":{ "index":3, "data":"a bank loan" }} ]}
原有实现代码:screen.tsx:
// 原代码存在语法错误、类型错误、逻辑错误 function App: React.FunctionComponent = ( ) => { const [blocks, setBlocks] = useState({ blocks: [] }); const getBlockData = async () => { const response = await fetch( `${some.url}/blocks` ).then((response) => response.json()); setBlocks(response); }; useEffect(() => { getBlockData(); }, []); return ( <div className="app"> { blocks.map((block: BlockType) => ( <div className="content"> Id:{block.id} <div> Type:{block.type} Index:{block.attributes.index} Data:{block.attributes.data} </div> </div> ))} </div> ); };
Block.ts类型定义:
export interface BlockType { id: string; type: string; attributes: { index: string; data: string; }; }
运行后抛出TS错误:Property 'map' does not exist on type '{ blocks: never[]; }'. TS2339,错误定位在blocks.map调用行。
错误原因
一共4个问题导致报错:
- 状态初始值类型错误:
useState初始化时传入的是对象{ blocks: [] },TypeScript自动推导blocks状态的类型为{ blocks: never[] },对象类型不存在数组的map方法,直接调用必然报类型错误。 - 接口字段取值错误:接口返回的数组挂载在
data字段下,原代码直接把整个接口响应对象赋值给blocks状态,和渲染逻辑预期的数组结构不匹配。 - 类型定义错误:接口返回的
attributes.index是数字类型,原类型定义写为string,后续渲染时会触发类型不匹配提示。 - 组件写法语法错误:
function App: React.FunctionComponent = () => {}混合了普通函数声明和箭头函数赋值的写法,本身不符合TS/JS语法规范。
修复步骤
- 修正类型定义文件
Block.ts,对齐接口返回字段类型:
export interface BlockType { id: string; type: string; attributes: { index: number; // 对齐接口返回的数字类型 data: string; }; }
- 修正
screen.tsx中的组件写法、状态初始化逻辑,明确状态类型为BlockType[],初始值设为空数组:
import { useState, useEffect } from 'react'; import type { BlockType } from './Block'; // 修正组件写法,用FC类型约束箭头函数组件 const App: React.FC = () => { // 初始值为空数组,明确状态为BlockType类型的数组 const [blocks, setBlocks] = useState<BlockType[]>([]); const getBlockData = async () => { try { const response = await fetch(`${some.url}/blocks`).then(res => res.json()); // 取接口返回的data字段赋值,兜底空数组避免异常 setBlocks(response.data ?? []); } catch (err) { console.error('获取块数据失败', err); setBlocks([]); } }; useEffect(() => { getBlockData(); }, []); return ( <div className="app"> {/* blocks现在是数组类型,可以正常调用map,列表项补充唯一key */} {blocks.map((block) => ( <div className="content" key={block.id}> Id:{block.id} <div> Type:{block.type} Index:{block.attributes.index} Data:{block.attributes.data} </div> </div> ))} </div> ); }; export default App;
修复后所有TS报错会消失,接口请求成功后可以正常渲染列表数据。
内容的提问来源于stack exchange,提问作者Andrey
相关产品推荐
相关产品推荐

