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

为何Partial Record的Object.values会出现undefined类型?

Partial<Record<string, number>> 取值类型推断问题解析

问题原因

Partial<Record<string, number>>的作用是把Record<string, number>的所有属性标记为可选,这意味着每个键对应的值类型变成了number | undefined。TypeScript是静态类型检查工具,只会依据类型定义做推断,不会分析你运行时实际给对象赋了哪些值。所以调用Object.values()时,类型系统默认认为每个值都可能是undefined,最终推断出的类型就是(number | undefined)[]——哪怕你实际给所有键都赋了确定的number值。

规避方法

1. 类型断言(简单直接,需自行保证数据安全)

直接把结果断言为number[],前提是你能确保对象里没有undefined值:

const obj: Partial<Record<string, number>> = { a: 1, b: 2 };
const values = Object.values(obj) as number[]; // 类型为number[]

2. 运行时类型守卫(更安全)

写一个类型守卫函数,在运行时检查数组中是否存在undefined,通过检查后TypeScript会自动把类型收窄为number[]:

function isAllNumbers(arr: (number | undefined)[]): arr is number[] {
  return arr.every(item => typeof item === 'number');
}

const obj: Partial<Record<string, number>> = { a: 1, b: 2 };
const values = Object.values(obj);
if (isAllNumbers(values)) {
  // 此处values类型自动推断为number[]
  console.log(values.map(n => n * 2));
}

3. 替换类型定义(从根源解决)

如果你的对象实际所有键都有确定的number值,没必要用Partial,直接用Record<string, number>定义类型:

const obj: Record<string, number> = { a: 1, b: 2 };
const values = Object.values(obj); // 类型自动为number[]

如果需要先创建一个部分赋值的对象再补全属性,可以先断言为Record<string, number>:

const obj = {} as Record<string, number>;
obj.a = 1;
obj.b = 2;
const values = Object.values(obj); // 类型为number[]

4. 用类型工具提取非undefined值类型

通过Exclude工具类型剔除undefined,再做断言:

type NumValue = Exclude<Partial<Record<string, number>>[string], undefined>;
const obj: Partial<Record<string, number>> = { a: 1, b: 2 };
const values = Object.values(obj) as NumValue[]; // 类型为number[]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 03:35:24