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

如何修正TypeScript中对象指定字段转数字的类型报错?

实现指定字段字符串转数字的TypeScript类型安全函数

我需要编写一个函数,将对象中指定字段的字符串值转换为数字,目前写了两个版本但都存在类型问题:

第一个函数版本

export function convertStringToNumber<K extends string>(
  obj: Record<K, object>,
  val: string
): Record<K, number> {
  const result: Partial<Record<K, unknown>> = {}
  for (const key in obj) {
    if (key === val) {
      result[key] = Number(obj[key])
    } else {
      result[key] = obj[key]
    }
  }
  return result as Record<K, number>
}

这个函数能正常运行,但TypeScript有类型报错,我希望TypeScript能根据输入类型,仅将指定键的类型改为数字,而不是把所有键都设为number类型。

第二个函数版本

export function convertStringToNumber2<T> (
  obj: T,
  val: string
): T {
  const result: Partial<T> = {}
  for (const key in obj) {
    if (key === val) {
      result[key] = Number(obj[key])
    } else {
      result[key] = obj[key]
    }
  }
  return result
}

此时TypeScript报错:Type 'number' is not assignable to type 'T[Extract<keyof T, string>]'.ts(2322),请问该如何解决?


解决方案

要实现类型安全的转换,需要利用TypeScript的映射类型和条件类型,精准修改指定键的类型:

export function convertStringToNumber<T, K extends keyof T>(
  obj: T,
  key: K
): Omit<T, K> & Record<K, number> {
  const result = { ...obj };
  result[key] = Number(obj[key]) as T[K] & number;
  return result as Omit<T, K> & Record<K, number>;
}

类型说明

  1. 泛型参数:
    • T:接收输入对象的完整类型
    • K:限制为T的键类型,确保传入的key是对象已存在的属性
  2. 返回类型:Omit<T, K> & Record<K, number>
    • Omit<T, K>:保留原对象除K之外的所有属性类型
    • Record<K, number>:将指定键K的类型改为number
    • 两者交叉后,得到仅修改指定键类型的新对象类型
  3. 实现细节:
    • 拷贝原对象避免修改源数据
    • 用Number()转换值,通过类型断言解决赋值时的类型冲突
    • 最后将结果断言为目标交叉类型

使用示例

const user = { name: "Alice", age: "25", score: "90" };
const convertedUser = convertStringToNumber(user, "age");
// convertedUser 类型为:{ name: string; score: string; } & { age: number; }
console.log(convertedUser.age); // 25(类型为number)

第二个版本报错的核心原因

第二个版本返回原类型T,但T中指定键的类型原本是string,转换后赋值为number必然不符合原类型约束。通过返回修改后的交叉类型而非原类型T,即可解决类型不匹配问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 16:15:43