如何动态访问对象键?TypeScript类型报错求助
解决TypeScript动态访问对象属性的类型报错
问题根源
你定义的fields是string[]类型,TypeScript无法确认其中的元素是record对象的合法键,因此直接使用record[fields[0]]会触发类型不匹配的报错。
解决方案
方案1:严格约束fields的类型
先修正类型定义(将数组类型与单个元素类型拆分),再把fields的类型限定为record对象的键集合,让TypeScript自动校验合法性:
// 定义单个record对象的类型 type RecordItem = { basic_monthly_mean: string, basic_monthly_median: string, degree: string, employment_rate_ft_perm: string, employment_rate_overall: string, gross_monthly_mean: string, gross_monthly_median: string, gross_mthly_25_percentile: string, gross_mthly_75_percentile: string, school: string, university: string, year: string, _id: number }; // 定义records数组 const records: RecordItem[] = []; // 替换为你的实际数据 // 约束fields只能包含RecordItem的合法键 const fields: Array<keyof RecordItem> = []; fields.push("year"); const data = { datasets: [ { label: 'Employment Rate Overall', data: records.map(record => { return { x: record[fields[0]], y: record.employment_rate_overall } }), backgroundColor: 'rgba(255, 99, 132, 1)', } ], };
方案2:访问时使用精确类型断言
如果无法修改fields的类型(比如它来自外部输入),可以在访问属性时直接断言当前键是record的合法键:
// 保持原类型定义(注意修正语法) type RecordItem = { // ... 你的属性定义 }; const records: RecordItem[] = []; var fields: string[] = []; fields.push("year"); const data = { datasets: [ { label: 'Employment Rate Overall', data: records.map(record => { // 断言fields[0]是RecordItem的合法键 return { x: record[fields[0] as keyof RecordItem], y: record.employment_rate_overall } }), backgroundColor: 'rgba(255, 99, 132, 1)', } ], };
方案3:添加类型守卫做运行时校验
如果fields的元素可能存在非法值,可以通过类型守卫同时做编译时校验和运行时判断:
type RecordItem = { // ... 你的属性定义 }; const records: RecordItem[] = []; var fields: string[] = []; fields.push("year"); // 类型守卫函数:判断键是否为RecordItem的合法键 function isValidRecordKey(key: string): key is keyof RecordItem { return Object.keys(records[0]).includes(key); } const data = { datasets: [ { label: 'Employment Rate Overall', data: records.map(record => { const targetKey = fields[0]; if (isValidRecordKey(targetKey)) { return { x: record[targetKey], y: record.employment_rate_overall }; } // 处理非法键的情况,比如返回默认值 return { x: '', y: record.employment_rate_overall }; }), backgroundColor: 'rgba(255, 99, 132, 1)', } ], };
注意点
你原有的类型定义type records: {...}[]语法有误,正确的做法是先定义单个元素的类型(如RecordItem),再用它声明数组类型const records: RecordItem[],这样后续的类型操作会更清晰。
内容的提问来源于stack exchange,提问作者Matt Daniel
相关产品推荐
相关产品推荐

