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

TypeScript mapKeys函数类型报错修复及返回键类型推断实现

修复mapKeys函数的TypeScript类型错误并实现键类型推断

问题描述

我编写了一个mapKeys函数,它接收重命名函数和对象,根据重命名函数对对象的键进行重命名,代码如下:

export default function mapKeys<T extends { [s: string]: T } | ArrayLike<T>>(
  renameFunction: (key: string) => string,
  object: T,
): T {
  return Object.fromEntries(
    Object.entries(object).map(([key, value]) => [renameFunction(key), value]),
  );
}

使用示例:

mapKeys(key => key.toUpperCase(), { a: 1, b: 2 });
// => { A: 1, B: 2 }

但该函数存在TypeScript类型报错:

  • 函数定义处:Type '{ [k: string]: T; }' is not assignable to type 'T'...
  • 调用处:Type 'number' is not assignable to type '{ a: number; b: number; }'

我需要修复这些错误,同时让TypeScript能够推断返回对象的键类型。例如当重命名函数为const rename = (a: string) => ${a}Error``,对象为{ email: 'foo' }时,TypeScript能识别返回对象的键为emailError。

我曾尝试改成以下写法,虽然能编译,但会丢失对象键的类型信息,无法推断返回对象的具体形状:

export default function mapKeys(
  renameFunction: (key: string) => string,
  object: object,
): object {
  return Object.fromEntries(
    Object.entries(object).map(([key, value]) => [renameFunction(key), value]),
  );
}

解决方案

要实现类型安全且支持键类型推断的mapKeys,需要利用TypeScript的模板字面量类型和泛型约束,让编译器跟踪键的转换关系:

1. 完整实现代码

// 定义键重映射后的对象类型
type MapKeys<T extends object, R extends string> = {
  [K in keyof T as R]: T[K];
};

export default function mapKeys<
  T extends object,
  R extends string,
  F extends (key: Extract<keyof T, string>) => R
>(
  renameFunction: F,
  object: T,
): MapKeys<T, ReturnType<F>> {
  return Object.fromEntries(
    Object.entries(object).map(([key, value]) => [renameFunction(key as Extract<keyof T, string>), value]),
  ) as MapKeys<T, ReturnType<F>>;
}

2. 验证效果

测试场景1:键转大写

const result1 = mapKeys(key => key.toUpperCase(), { a: 1, b: 2 });
// TypeScript自动推断返回类型:{ A: number; B: number }

测试场景2:键添加固定后缀

const rename = (a: string) => `${a}Error` as const;
const result2 = mapKeys(rename, { email: 'foo' });
// TypeScript自动推断返回类型:{ emailError: string }

关键说明

  • MapKeys类型:通过as关键字实现键的重映射,将原对象的键K替换为目标键类型R
  • 泛型F:约束重命名函数的参数为输入对象的字符串键,返回值为新键类型,确保类型推断的准确性
  • Extract<keyof T, string>:处理对象键可能包含number或symbol的情况,仅保留字符串类型的键用于重命名
  • 类型断言:Object.fromEntries默认返回宽松的{[key: string]: T[K]}类型,通过断言转为我们定义的精确键类型

内容的提问来源于stack exchange,提问作者J. Hesters

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 20:01:44