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

TypeScript动态赋值对象属性报string无法分配给never类型错误

TypeScript 表单赋值类型报错修复

问题现象

开发表单编辑功能时,editCloneStateForm 方法执行表单字段赋值时报错:Type 'string' is not assignable to type 'never',报错位置为else分支的this.form[key] = value行。此前尝试将value参数类型设置为typeof this.form仍未解决问题。

业务代码

editCloneStateForm (value: string, key: IServiceDoneItemKeys) {
    if (this.index >= 0) {
      this.cloneStateForm[this.index].cdate = value
    } else {
      this.form[key] = value // 报错位置
    }
  }

form: IServiceDoneItem = {
    id: 0,
    cdate: '',
    counterparty_id: '',
    counterparty_name: '',
    contract_id: '',
    contract_number: '',
    service_id: '',
    statement_id: null,
    service_count: 0,
    cost: 0,
    income: 0,
    agents_commission: 0,
    state_duty: 0,
    ukap: ''
  }

类型定义

export interface IServiceDoneItem {
  id?: number,
  cdate: string,
  counterparty_id: number | string,
  counterparty_name: string,
  contract_id: number | string,
  contract_number: string,
  service_id: number | string,
  statement_id: number | null,
  service_count: number,
  cost: number,
  income: number,
  agents_commission: number,
  state_duty: number,
  ukap: string
}

export type IServiceDoneItemKeys = keyof IServiceDoneItem

报错原因

key的类型是IServiceDoneItem所有字段名的联合类型,当使用联合类型的通用key做对象索引赋值时,TypeScript会推导目标赋值位置的类型为所有字段类型的交叉类型,用来保证无论传入哪个合法key,赋值操作都类型安全。当前接口字段类型包含string/number/null等无公共交集的类型,交叉运算结果为never,因此string类型的value无法赋值给never类型的位置。

修复方案

方案1:泛型约束(推荐,类型安全)

通过泛型绑定key和对应value的类型关系,让TS自动校验字段和值的类型匹配:

// 改造方法签名,增加泛型约束
editCloneStateForm<K extends IServiceDoneItemKeys>(
  value: IServiceDoneItem[K], 
  key: K
) {
    if (this.index >= 0) {
      // 该分支固定赋值cdate字段(string类型),做类型断言即可
      this.cloneStateForm[this.index].cdate = value as string
    } else {
      this.form[key] = value
    }
}

调用该方法时,TS会自动根据传入的key校验value类型是否匹配,例如传入key: 'service_count'时,value必须传入number类型,从根源避免类型错误。

方案2:类型断言(快速修复,需自行保证类型安全)

如果不想调整方法签名,可直接对赋值位置做类型断言,跳过TS校验:

editCloneStateForm (value: string, key: IServiceDoneItemKeys) {
    if (this.index >= 0) {
      this.cloneStateForm[this.index].cdate = value
    } else {
      // 断言为字段联合类型,需业务侧保证传入的key对应的字段实际可接收string类型值
      this.form[key] = value as IServiceDoneItem[IServiceDoneItemKeys]
    }
  }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:27:21