TypeScript中如何将Report对象转换为扩展的ReportForm类型?
问题背景
我们有API返回的JSON数据如下:
{ "id": 1, "name": "March 2022", "metrics": [ { "name": "Visual", "priority": "normal" }, { "name": "Spoken", "priority": "high" } ] }
对应的TypeScript接口定义:
interface Report { id: number; name: string; metrics: Array<{ name: string; priority: string; }>; }
为满足表单验证需求,我们基于Report扩展出ReportForm接口,新增错误相关属性:
interface ReportForm extends Report { nameError: string; metrics: Array<{ name: string; priority: string; nameError: string; priorityError: string; }>; }
尝试将API返回的Report对象转换为ReportForm类型时,出现错误:Cannot assign to read only property 'nameError' of object。
解决方法
错误根源是API返回的对象可能被标记为只读(比如fetch解析后的响应对象属性默认不可写),或者直接修改了原对象的属性。正确做法是创建全新的可写对象,而非修改原Report对象:
单个对象转换
const convertToReportForm = (report: Report): ReportForm => { return { ...report, // 复制原Report的所有属性 nameError: '', // 初始化错误字段为空 metrics: report.metrics.map(metric => ({ ...metric, // 复制原metric的属性 nameError: '', priorityError: '' })) }; };
数组批量转换
如果需要处理Report数组,直接遍历调用单个转换函数即可:
const convertReportsToForms = (reports: Report[]): ReportForm[] => { return reports.map(report => convertToReportForm(report)); };
核心要点
- 使用对象扩展运算符
...复制原对象属性,生成独立的新对象,避开原只读对象的限制。 - 对
metrics数组的每个元素也执行相同的复制+新增字段操作,确保所有子对象都是可写的。 - 错误字段初始化为空字符串,后续表单验证时可直接更新这些字段的值。
内容的提问来源于stack exchange,提问作者Anurag Deore
相关产品推荐
相关产品推荐

