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

TypeScript类型适配问题:实现输入输出键对应类转换函数

问题解决:动态生成对应类实例的函数实现

错误原因分析

  1. Type 'string' is not assignable to type 'keyof OutputObject':原代码泛型K extends keyof TObj中,TObj是Partial<InputObject>,TypeScript无法确定遍历的键属于keyof OutputObject,导致类型不匹配。
  2. Type 'Partial' is not assignable to type 'Pick<OutputObject, K>':Partial<OutputObject>允许所有字段可选,但Pick<OutputObject, K>要求选中的K字段必须存在且类型匹配,二者类型不兼容。

优化后的实现方案

通过类型映射和动态遍历输入键解决问题,同时让函数支持后续扩展新字段:

class A {
  constructor(public value: number) {} // 接收初始化数值
}
class B {
  constructor(public value: number) {}
}

// 集中管理输入键与对应类的映射,新增字段只需在此添加
type ClassMap = {
  a: typeof A;
  b: typeof B;
  // 后续新增c、d时,直接添加:c: typeof C; d: typeof D;
};

// 自动推导输入类型:每个键对应可选的number类型
type InputObject = { [K in keyof ClassMap]?: number };

// 自动推导输出类型:每个键对应对应类的实例
type OutputObject = { [K in keyof ClassMap]: InstanceType<ClassMap[K]> };

const fn = <K extends keyof ClassMap>(x: Pick<InputObject, K>): Pick<OutputObject, K> => {
  const returnValue = {} as Pick<OutputObject, K>;

  // 动态遍历输入键,避免硬编码,提升扩展性
  for (const key in x) {
    if (x[key] !== undefined) {
      const ClassConstructor = ClassMap[key];
      returnValue[key] = new ClassConstructor(x[key]!) as InstanceType<ClassMap[K]>;
    }
  }

  return returnValue;
};

// 测试用例
const result1 = fn({ a: 1, b: 1 }); // { a: A, b: B }
const result2 = fn({ b: 2 }); // { b: B }
const result3 = fn({}); // {}

代码说明

  1. 类型映射ClassMap:统一管理输入键与类的关联,新增字段时只需在此添加对应关系,无需修改函数逻辑。
  2. 自动推导类型:利用TypeScript映射类型,从ClassMap自动生成InputObject和OutputObject,减少重复定义。
  3. 动态遍历处理:通过for...in遍历输入对象的键,动态创建对应类的实例,避免硬编码a、b。
  4. 类型断言:使用as Pick<OutputObject, K>和as InstanceType<ClassMap[K]>帮助TypeScript正确推断类型,解决类型不匹配问题。

原代码报错核心原因

  • 原泛型定义未明确关联K与OutputObject的键,导致TypeScript无法确认键的合法性。
  • Partial<OutputObject>是全可选类型,但函数返回的应该是输入存在的键必须对应存在实例的类型,二者类型不兼容,因此需要使用Pick<OutputObject, K>配合类型断言确保类型正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 09:05:27