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

为对象键映射函数createMapper添加正确的TypeScript类型定义

解决 createMapper 函数的 TypeScript 类型问题

问题分析

当前类型定义未正确关联映射规则、源对象与返回对象的类型关系,导致源对象属性校验报错、返回对象无自动补全。需通过泛型约束和类型推导实现类型安全与自动补全。

修正后的完整实现

type KeyMap = Record<string, string>;

function createMapper<Map extends KeyMap>(map: Map) {
  return function<Source extends Partial<Record<keyof Map, any>>>(
    objectToMap: Source
  ): { [K in Map[keyof Map]]: K extends Map[keyof Map] ? Source[keyof { [P in keyof Map]: Map[P] extends K ? P : never }] : never } {
    const result = {} as any;
    for (const [sourceKey, targetKey] of Object.entries(map)) {
      if (objectToMap.hasOwnProperty(sourceKey)) {
        result[targetKey] = objectToMap[sourceKey as keyof Source];
      }
    }
    return result;
  };
}

用法示例

// 创建映射器:将a映射到username,b映射到age
const mapper = createMapper({ a: 'username', b: 'age' });

// 源对象可包含映射规则中的部分或全部键
const source = { a: 'Alice', b: 25 };
const mapped = mapper(source);

// mapped 自动补全 username 和 age 属性,类型分别为 string 和 number
console.log(mapped.username); // 类型安全,支持自动补全
console.log(mapped.age); // 类型安全,支持自动补全

类型说明

  1. 泛型Map:约束传入的键映射对象为字符串键值对,TypeScript会自动推导映射规则的具体键值。
  2. 泛型Source:约束源对象包含映射规则中的部分或全部键(通过Partial<Record<keyof Map, any>>实现),解决源对象属性报错问题。
  3. 返回类型推导:通过条件类型和映射类型,将映射规则的目标键与源对象的对应值类型关联,实现返回对象的属性自动补全和类型安全。

可选优化(严格值类型约束)

允许用户通过泛型显式指定源对象类型,进一步强化类型安全:

function createMapper<Map extends KeyMap>(map: Map) {
  return function<Source extends Partial<Record<keyof Map, any>>>(
    objectToMap: Source
  ): { [K in Map[keyof Map]]: Extract<keyof Source, { [P in keyof Map]: Map[P] extends K ? P : never }[keyof Map]> extends infer S ? S extends keyof Source ? Source[S] : never : never } {
    const result = {} as any;
    for (const [sourceKey, targetKey] of Object.entries(map)) {
      if (objectToMap.hasOwnProperty(sourceKey)) {
        result[targetKey] = objectToMap[sourceKey as keyof Source];
      }
    }
    return result;
  };
}

// 显式指定源对象类型
type UserSource = { a: string; b: number };
const mapper = createMapper({ a: 'username', b: 'age' });
const mapped = mapper<UserSource>({ a: 'Bob', b: 30 });

内容的提问来源于stack exchange,提问作者Islam Y-

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 17:46:15