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

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

解决TypeScript中“Type 'number' is not assignable to type 'never'”报错

你猜的没错,问题根源就是接口DetailedRankings里同时存在string和number类型的属性。

当你用keyof DetailedRankings作为category的参数类型时,这个参数可能指向name、category这类值为string的属性,也可能指向show_id、story这类值为number的属性。你把number类型的value_number赋值给obj[category]时,TypeScript会做严格的类型检查:它会取所有可能属性类型的交集,而string和number的交集是never,所以就出现了这个报错。

下面是几种可行的解决方法:

方案一:缩小参数类型范围(最推荐)

定义一个类型,只提取DetailedRankings中值为number的属性键,让category只能接收这些键:

export interface DetailedRankings {
  show_id: number;
  name: string;
  category: string;
  episodes: number;
  story?: number;
  characters?: number;
  overall?: number;
}

// 提取对象中值为number类型的键
type NumericKeysOf<T> = { 
  [K in keyof T]: T[K] extends number ? K : never 
}[keyof T];

function handleInputChange(
  category: NumericKeysOf<DetailedRankings>, 
  event: string, 
  index: number
) {
  const value_number: number = parseFloat(event);
  let list: DetailedRankings[] = [...detailed_ranks];
  let obj: DetailedRankings = list[index];
  obj[category] = value_number; // 不再报错
}

这种方式能在编译阶段就阻止传入name、category这类不匹配的键,类型安全性最高。

方案二:使用类型守卫做运行时判断

如果需要保留category接收所有键的灵活性,但只在对应number属性时赋值,可以用类型守卫:

export interface DetailedRankings {
  show_id: number;
  name: string;
  category: string;
  episodes: number;
  story?: number;
  characters?: number;
  overall?: number;
}

// 预先定义所有number类型属性的键集合
const numericPropertyKeys = new Set<string>([
  'show_id', 'episodes', 'story', 'characters', 'overall'
]);

function handleInputChange(
  category: keyof DetailedRankings, 
  event: string, 
  index: number
) {
  const value_number: number = parseFloat(event);
  let list: DetailedRankings[] = [...detailed_ranks];
  let obj: DetailedRankings = list[index];
  
  // 判断当前category是否属于number属性的键
  if (numericPropertyKeys.has(category as string)) {
    obj[category as keyof Pick<DetailedRankings, 'show_id' | 'episodes' | 'story' | 'characters' | 'overall'>] = value_number;
  }
}

这种方式需要维护numericPropertyKeys集合,当接口修改时要同步更新,但保留了参数的灵活性。

方案三:类型断言(不推荐,仅临时应急)

如果你能100%确保传入的category一定是number属性的键,可以用类型断言跳过检查:

function handleInputChange(category: keyof DetailedRankings, event: string, index: number) {
  const value_number: number = parseFloat(event);
  let list: DetailedRankings[] = [...detailed_ranks];
  let obj: DetailedRankings = list[index];
  // 断言category指向number类型的属性
  obj[category as 'show_id' | 'episodes' | 'story' | 'characters' | 'overall'] = value_number;
}

这种方式会绕过TypeScript的类型检查,一旦传入错误的键,运行时可能出问题,不建议长期使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 12:54:23