You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 07:05:18