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

React+TypeScript中调用Map.size属性及遍历Map报错问题

问题产生原因
  • 你自定义的TMap<T>是带字符串索引签名的普通JavaScript对象类型,和ES6标准内置的Map类型完全不是一回事。普通对象没有内置的.size属性,本身也不是可迭代对象,因此运行时读取.size、调用Array.from()遍历都会触发报错。
  • TypeScript没有提前抛出类型错误,是因为你手动给组件props标注了错误的类型,TS会按照你定义的类型规则做校验,无法自动识别你实际传入的值是Map实例、和你声明的类型不匹配的问题。
修复方案

根据你实际要传入的数据类型二选一即可:

方案1:传入的是ES6原生Map实例(和你的初始需求匹配)

直接删除你自定义的错误TMap类型,使用TypeScript内置的Map泛型类型定义props即可,原有业务逻辑不需要调整:

import * as Styled from './assignments-list.styles'

// 删除自定义的TMap类型,直接使用内置Map类型
type TAssignmentsListProps = {
    assignments: Map<string, string>
}

const AssignmentsList = ({assignments}: TAssignmentsListProps) => {
    return (
        <Styled.AssignmentsList>
            <Styled.Header> 
                Assignments
            </Styled.Header>
                {
                    (assignments && assignments.size !== 0) ?
                    <Styled.ListFiles>
                        {
                            Array.from(assignments).map(([name, url]) => {
                                return (
                                    <li key={name}> 
                                        <Styled.ListItemWrapper>
                                            <Styled.FileName>
                                                {name}
                                            </Styled.FileName>
                                            <Styled.RemoveFile>
                                                View
                                            </Styled.RemoveFile>
                                        </Styled.ListItemWrapper>
                                    </li>
                                )
                            })
                        }
                    </Styled.ListFiles> :
                    <Styled.BodyText>None</Styled.BodyText>
                }
        </Styled.AssignmentsList>
    )
}

export default AssignmentsList

原生Map实例本身自带.size属性,同时实现了可迭代协议,Array.from()可以直接将其转为键值对数组,和你写的逻辑完全适配。

方案2:传入的是普通键值对对象

如果你实际不需要用Map的特性,只是传普通的string键值对对象,那就保留你原来的类型定义,调整对应的读取和遍历逻辑即可:

{
  (assignments && Object.keys(assignments).length !== 0) ?
  <Styled.ListFiles>
    {
      Object.entries(assignments).map(([name, url]) => {
        // 原有渲染逻辑保持不变
        return (
          <li key={name}> 
            <Styled.ListItemWrapper>
              <Styled.FileName>
                {name}
              </Styled.FileName>
              <Styled.RemoveFile>
                View
              </Styled.RemoveFile>
            </Styled.ListItemWrapper>
          </li>
        )
      })
    }
  </Styled.ListFiles> :
  <Styled.BodyText>None</Styled.BodyText>
}

普通对象没有.size属性,需要通过Object.keys()拿到键数组后读取长度判断是否为空,遍历键值对需要用Object.entries()方法。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 00:37:03