TypeScript中使用对象Key访问属性时的类型报错问题
解决TypeScript中表格行索引的类型错误问题
问题原因
你遇到的错误是因为column.key的类型被TypeScript推断为宽泛的string,但rows<T>的键是T[number]["key"]对应的具体联合类型(比如当columns是[{key:'name'}, {key:'age'}]时,键类型是'name'|'age')。用string类型去索引一个键为具体联合类型的对象,TypeScript无法确定索引的合法性,所以抛出隐式any类型的错误。
解决方案
方案1:优化类型定义,使用泛型约束键的字面量类型
通过给Column类型添加泛型参数,让key的类型从宽泛的string变为具体的字面量类型,这样TypeScript就能准确推断出索引的类型:
// 定义带泛型的Column类型,约束key为具体的字符串字面量 type Column<K extends string> = { key: K; label: string; }; // 根据Column的key类型生成Rows的结构 type Rows<T extends Column<string>> = { [K in T["key"]]: string; }; // 调整Props的泛型约束为Column的联合类型 interface TableBodyProps<T extends Column<string>> { columns: T[]; tableRows: Rows<T>[]; } const TableBody = <T extends Column<string>>({ columns, tableRows, }: TableBodyProps<T>) => { tableRows.forEach((row) => { columns.forEach((column) => { // 此时column.key的类型是T["key"],与row的键类型完全匹配 console.log(row[column.key]); }); }); };
方案2:类型断言快速修复(适合临时场景)
如果不想修改原有类型定义,可以通过类型断言告诉TypeScriptcolumn.key是row的合法键:
// 保留你原来的类型定义 type column = { key: string; label: string; }; type rows<T extends column[]> = { [key in T[number]["key"]]: string; }; interface TableBodyProps<T extends column[]> { columns: T; tableRows: rows<T>[]; } const TableBody = <T extends column[]>({ columns, tableRows, }: TableBodyProps<T>) => { tableRows.forEach((row) => { columns.forEach((column) => { // 断言column.key是row的键类型 console.log(row[column.key as keyof rows<T>]); }); }); };
测试验证
使用as const让columns的key保持字面量类型,确保类型检查生效:
const testColumns = [ { key: "name", label: "姓名" }, { key: "age", label: "年龄" }, ] as const; const testRows = [ { name: "张三", age: "25" }, { name: "李四", age: "30" }, ]; // 此时不会有类型错误 TableBody({ columns: testColumns, tableRows: testRows });
内容的提问来源于stack exchange,提问作者lentil-soup
相关产品推荐
相关产品推荐

