You need to enable JavaScript to run this app. Typescript如何提取const对象的值类型作为新类型的键并实现类型安全函数
优惠活动
大模型
产品
解决方案
定价
更多

Typescript如何提取const对象的值类型作为新类型的键并实现类型安全函数

报错原因

报错本质是TypeScript类型系统的推导能力限制:

  • 对于KeysAsKeys<T>,它的键集合直接和T的键集合完全匹配,TS可以直接确认Partial<KeysAsKeys<T>>和KeysAsKeys<T>的类型是兼容的,因此强制断言可以通过。
  • 但ValuesAsKeys<T>是通过键重映射生成的新类型,TS没有办法自动建立「T的所有值的集合」和「ValuesAsKeys<T>的键集合」的等价关联:既无法确认循环遍历所有值后已经填满了所有需要的键,也无法处理多个键对应同一个值时的自动去重场景,因此直接将Partial<ValuesAsKeys<T>>断言为ValuesAsKeys<T>会被判定为类型不兼容。

解决方案

可以通过双重断言绕过TS的类型兼容性检查,业务逻辑本身可以保证最终返回的对象符合ValuesAsKeys<T>类型,不会有运行时问题。修改后的代码如下:

type BaseObject = Record<string, string>;

type ValuesAsKeys<T extends BaseObject> = {
    [K in keyof T as T[K]]: number;
};

function useValuesAsKeys<T extends BaseObject>(arg: T): ValuesAsKeys<T> {
  const x: Partial<ValuesAsKeys<T>> = {};
  for (const value of Object.values(arg) as Array<T[keyof T]>) {
    x[value] = 1;
  }
  // 先转为unknown再断言为目标类型,绕过TS的限制
  return x as unknown as ValuesAsKeys<T>;
}

// 测试用例
const obj = {key1: 'value1', key2: 'value2'} as const;
const result = useValuesAsKeys(obj); 
// result的类型正确推导为 { value1: number; value2: number }

如果需要更强的类型安全,可以额外加泛型约束限制输入的T的所有值都是唯一字符串,日常业务场景下上述方案已经足够使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 04:15:00