使用Array.map渲染React组件时出现类型不兼容错误求助
问题描述
我想基于payload数组数据遍历渲染React组件,写了如下代码:
interface PayloadItemInterface { login: string } const QueriesAccordion=()=>{ const SearchPage = useContext(SearchPageContext); const {searchPayload} = SearchPage; const {payload} = searchPayload; return ( <Accordion> {payload.length > 0 ? payload.map((x:PayloadItemInterface, id) => <Accordion.Item eventKey={`${id}`}> <Accordion.Header>{x.login}</Accordion.Header> <Accordion.Body> Lorem ipsum dolor sit amet. </Accordion.Body> </Accordion.Item> ): null} </Accordion> ); };
但代码返回以下错误:
- Argument of type '(x: PayloadItemInterface, id: number) => Element' is not assignable to parameter of type '(value: {}, index: number, array: {}[]) => Element'.
- Argument of type '(x: PayloadItemInterface, id: number) => Element' is not assignable to parameter of type '(value: {}, index: number, array: {}[]) => Element'.
Types of parameters 'x' and 'value' are incompatible.
Property 'login' is missing in type '{}' but required in type 'PayloadItemInterface'.
我已经通过PayloadItemInterface指定了login属性,为什么还是报错?补充:数组中每个对象的结构如下:
{ "login": "foo", "id": 1, "node_id": "MDQ6", "avatar_url": "https://foo", "gravatar_id": "", "url": "https://api.github.com/users/foo", "html_url": "https://github.com/mojombo", "followers_url": "https://api.github.com/users/foo/followers", "following_url": "https://api.github.com/users/foo/following{/other_user}", "gists_url": "https://api.github.com/users/foo/gists{/gist_id}", "starred_url": "https://api.github.com/users/foo/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/foo/subscriptions", "organizations_url": "https://api.github.com/users/foo/orgs", "repos_url": "https://api.github.com/users/foo/repos", "events_url": "https://api.github.com/users/foo/events{/privacy}", "received_events_url": "https://api.github.com/users/foo/received_events", "type": "User", "site_admin": false }
原因及解决方法
报错原因
TypeScript无法推断出searchPayload.payload的具体类型,默认将其识别为{}[](空对象数组)。你仅在map回调里给x指定PayloadItemInterface类型,会和TS推断的{}类型产生冲突,因此报错。
解决步骤
完善数据类型定义
根据你提供的数组项结构,补全完整的类型:interface PayloadItemInterface { login: string; id: number; node_id: string; avatar_url: string; gravatar_id: string; url: string; html_url: string; followers_url: string; following_url: string; gists_url: string; starred_url: string; subscriptions_url: string; organizations_url: string; repos_url: string; events_url: string; received_events_url: string; type: string; site_admin: boolean; }若部分字段可能为空,可添加
?将其设为可选属性,例如gravatar_id?: string;。给Context指定明确类型
找到SearchPageContext的定义位置,为其value指定类型:// 定义Context的类型结构 interface SearchPageContextType { searchPayload: { payload: PayloadItemInterface[]; // 若searchPayload还有其他属性,在此补充 }; // 补充Context中的其他方法或属性 } // 创建Context时绑定类型及默认值 const SearchPageContext = createContext<SearchPageContextType>({ searchPayload: { payload: [] }, // 其他默认值按需补充 });简化组件内的类型推断
完成上述定义后,组件中无需再手动给map的x指定类型,TS会自动推断:const QueriesAccordion=()=>{ const {searchPayload} = useContext(SearchPageContext); const {payload} = searchPayload; return ( <Accordion> {payload.length > 0 ? payload.map((x, id) => <Accordion.Item key={id} eventKey={`${id}`}> <Accordion.Header>{x.login}</Accordion.Header> <Accordion.Body> Lorem ipsum dolor sit amet. </Accordion.Body> </Accordion.Item> ): null} </Accordion> ); };注意给
Accordion.Item添加key属性,React遍历列表需要唯一标识,若数据中有更稳定的唯一值(如node_id),优先使用该值作为key。临时应急方案(不推荐长期使用)
若暂时不想修改Context类型,可在组件内对payload做类型断言:const payload = searchPayload.payload as PayloadItemInterface[];此方法会跳过TS的类型检查,仅适合临时调试使用。
内容的提问来源于stack exchange,提问作者gfek
相关产品推荐
相关产品推荐

