如何在TypeScript中将空字符串转为null?解决索引类型报错
TypeScript遍历对象将空字符串转null的类型报错解决
问题背景
我是TypeScript新手,之前只浅尝辄止。定义了两个接口,其中一个用来读取不受我控制的数据库数据,没法保证返回值符合预期:
// 从数据库获取的接口 interface JobTableRow { job_number: string, description: string | null, project_manager: string | null, status: string | null, ts_customer_id: string | null, completed_date: string | null, date_stamp: string, time_stamp: string, contract_base: number, contract_approved_changes: number, contract_revised_total: number, jtd_cost: number, start_date: string | null, labor_tax_group: string | null, material_tax_group: string | null, subcontract_tax_group: string | null, equipment_tax_group: string | null, overhead_tax_group: string | null, other_tax_group: string | null, ts_row_id: string, ts_row_version: string } // 从数据库获取后手动计算字段的接口 interface JobMapping extends JobTableRow { ts_updated: string }
示例数据:
const mapped: JobMapping = { job_number: '0000', description: 'some project', project_manager: 'some person', status: 'active', date_stamp: '2020-04-20', time_stamp: '11:12:57', labor_tax_group: '', material_tax_group: '', subcontract_tax_group: '', equipment_tax_group: '', overhead_tax_group: '', other_tax_group: '', // ... ts_updated: '2020-04-20T18:12:57.000Z' }
尝试用以下代码把空字符串转为null时,TypeScript抛出错误:Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'JobMapping'. No index signature with a parameter of type 'string' was found on type 'JobMapping'.ts(7053)
报错代码:
Object.keys(mapped).forEach(key => { if (typeof mapped[key] === 'string') { let val: string = mapped[key] if (val === '') mapped[key] = null } })
解决方法
方法1:类型断言缩小键范围
把遍历到的key断言为keyof JobMapping,同时确保只给允许为null的字段赋值:
Object.keys(mapped).forEach((key) => { const typedKey = key as keyof JobMapping; const value = mapped[typedKey]; // 仅处理类型为 string | null 的字段,避免给不允许为null的字段(如date_stamp)赋值 if (typeof value === 'string' && value === '') { mapped[typedKey] = null as typeof mapped[typedKey]; } })
方法2:添加索引签名
给接口添加字符串索引签名,让TypeScript允许任意字符串键访问,但会损失部分类型安全性:
interface JobTableRow { // 保留原有所有字段 job_number: string, description: string | null, project_manager: string | null, status: string | null, ts_customer_id: string | null, completed_date: string | null, date_stamp: string, time_stamp: string, contract_base: number, contract_approved_changes: number, contract_revised_total: number, jtd_cost: number, start_date: string | null, labor_tax_group: string | null, material_tax_group: string | null, subcontract_tax_group: string | null, equipment_tax_group: string | null, overhead_tax_group: string | null, other_tax_group: string | null, ts_row_id: string, ts_row_version: string, // 添加索引签名 [key: string]: string | number | null; } interface JobMapping extends JobTableRow { ts_updated: string }
添加后原有的遍历代码即可正常运行,但TypeScript不再检查键的有效性。
方法3:显式枚举目标字段
如果只有特定字段需要转换,直接枚举这些字段,类型安全性最高:
// 列出所有允许为null的字符串字段 const nullableStringFields: (keyof JobMapping)[] = [ 'description', 'project_manager', 'status', 'ts_customer_id', 'completed_date', 'start_date', 'labor_tax_group', 'material_tax_group', 'subcontract_tax_group', 'equipment_tax_group', 'overhead_tax_group', 'other_tax_group' ]; nullableStringFields.forEach(key => { if (mapped[key] === '') { mapped[key] = null; } });
内容的提问来源于stack exchange,提问作者alilland
相关产品推荐
相关产品推荐

