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

TypeScript报错:Type 'string'无法赋值给'never'类型求助

类型错误:Type 'string' is not assignable to type 'never' 问题排查

错误场景

执行以下代码行时触发类型错误:

rowData[headerKey] = value;

错误提示:

Type 'string' is not assignable to type 'never'.ts(2322)
const headerKey: never

相关业务代码

const exportData = (
    table.getSortedRowModel().rows.length > 0
      ? table.getSortedRowModel().rows // 使用排序后的数据(如果存在)
      : table.getCoreRowModel().rows
  ).map((row) => {
    const rowData: Partial<TableDataGeneralTemp> = {};
    row.getVisibleCells().forEach((cell) => {
      if (cell.column.columnDef.header !== "IsSelected") {
        const value = cell.getValue() as string;
        const headerKey = cell.column.columnDef.header as keyof TableDataGeneralTemp; 

        rowData[headerKey] = value;
      }
    });
    return rowData;
  });

接口定义

interface TableData1 {
  application_date: string; // ISO 8601 日期字符串
  application_id: string;
  applicant_name: string;
  institution?: string;
  applicant_email?: string;
  status: string;
  payment_status: string;
}

interface TableData2 {
  document_Request_Workflow_No: string;
  document_Request_Name: string;
  status: string;
  created: string;
  last_Updated: string;
}

interface TableData3 {
  invoice_no: string;
  gross_revenue: string;
  payment_status: string;
  payment_method: string;
  platform_fee: string;
  net_revenue: string;
}

interface DocStatusData {
  document_request_status_no: string;
  application_id: string;
  document_name: string;
  type_of_copy: string;
  status: string;
}

interface InvoiceData {
  invoice_date: string;
  invoice_no: string;
  payment_date: string;
  amount: string;
  status: string;
}

interface ReceiptData {
  receipt_date: string;
  transaction_no: string;
  payment_date: string;
  status: string;
}

interface CommonTableData {
  isSelected: boolean;
}

type TableDataGeneralTemp =
  | TableData1
  | TableData2
  | TableData3
  | DocStatusData
  | InvoiceData
  | ReceiptData;
type TableDataGeneral = (
  | TableData1
  | TableData2
  | TableData3
  | DocStatusData
  | InvoiceData
  | ReceiptData
) &
  CommonTableData;

已尝试的无效方案

添加安全校验后问题未解决:

if (headerKey && headerKey in rowData) {
    rowData[headerKey as keyof TableDataGeneralTemp] = value;
}

问题原因与解决方案

核心原因

TableDataGeneralTemp是联合类型,keyof TableDataGeneralTemp仅会提取所有子类型的共有键(此处只有status)。但实际代码中headerKey可能是某个子类型独有的键,TypeScript无法确定该键属于联合类型中的哪一个子类型,最终推导headerKey为never,导致赋值时类型不匹配。

同时,Partial<TableDataGeneralTemp>是各子类型Partial版本的联合,而非所有子类型属性的集合,进一步加剧了类型推导矛盾。

可行解决方案

方案1:转为交叉类型的Partial

将rowData的类型定义为所有子接口属性的交叉类型的Partial,让TypeScript识别所有可能的键:

// 提取所有子类型的属性集合
type TableDataAllProps = TableData1 & TableData2 & TableData3 & DocStatusData & InvoiceData & ReceiptData;
// 允许所有属性可选
const rowData: Partial<TableDataAllProps> = {};

方案2:临时类型断言(快速绕过)

如果不需要严格的类型检查,可以断言为任意字符串键的对象:

(rowData as Record<string, string>)[headerKey] = value;

方案3:缩小联合类型范围

若能确定当前表格仅展示某一子类型的数据,可添加类型守卫缩小rowData的类型范围,例如:

// 假设当前处理的是TableData1类型的数据
const rowData: Partial<TableData1> = {};
// 配合对应的类型守卫逻辑(如判断表格标识)

内容的提问来源于stack exchange,提问作者user19116203

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 05:43:11