TypeScript嵌套map遍历接口数据时r[c.field]报隐式any错误如何解决
嵌套map遍历索引对象报TS类型错误的修复方案
错误根因
报错的核心原因是类型定义不匹配:
- 你当前定义的
columns数组中,field字段的类型是宽泛的string - 但
rows数组的元素对象只有固定的4个键:id/order/name/timeRequired
TypeScript不允许用无约束的任意字符串去索引键名固定的对象,因此抛出类型错误。之前用keyof MyClass修复失败,是因为既没有把field的类型和行数据的键做绑定,MyClass也和当前的行数据类型不对应,该问题和TS配置缺失无关。
修复方法
方案1:从根源收紧类型定义(推荐)
把行数据的类型抽离复用,将columns的field字段类型约束为行数据的合法键,从定义层面避免非法字段传入:
type RowItem = { id: string; order: number; name: string; timeRequired: number; }; interface Props { // 这里把field的类型从string改成keyof RowItem,限定只能传行数据存在的键 columns: Array<{field: keyof RowItem, headerName: string, width: number}>; rows: Array<RowItem>; handleSortOrder: (id: string, order: number, type: string) => void; path: string; updateSortOrder: MouseEventHandler<HTMLButtonElement>; loading: boolean; }
改完之后原来的{r[c.field]}不会再抛错,TS还会自动校验你传入的columns配置里的field值是否合法。
方案2:临时类型断言(适合无法修改Props定义的场景)
如果columns的类型是外部传入、暂时无法修改,可以在取值时做针对性的类型断言,注意断言的目标类型要和当前行数据的类型一致,不要用无关的自定义类名:
{ rows.map((r) => ( // 给遍历项加唯一key,避免React渲染警告 <tr key={r.id} className='micro-course-resource-table-row'> {columns.map((c) => ( // 列key用c.field即可,同一行内field值唯一 <td key={c.field} className='micro-course-td'> <div role='button' tabIndex={-1} onKeyDown={() => navigate(`/${path}/${r.id}`)} onClick={() => navigate(`/${path}/${r.id}`)} > {/* 这里做类型断言 */} {r[c.field as keyof typeof r]} </div> </td> ))} </tr> )); }
注意:用断言方案时要自行保证传入的
columns里所有field值都在行数据里存在,否则运行时会取到undefined。
内容的提问来源于stack exchange,提问作者thegreenedition
相关产品推荐
相关产品推荐

