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

为支持泛型Schema的转换函数添加正确TypeScript类型

解决方案:为字段映射函数添加TypeScript泛型类型约束

核心需求

将单字符命名的API响应类型(如AB)自动映射到可读性更强的目标类型(如XY),同时为映射函数convert及映射规则mapping添加严格的TypeScript类型约束,消除any类型。

类型定义与实现

1. 定义嵌套映射类型Mapping<T, U>

该类型约束mapping对象的结构:

  • 键必须是原始类型T的所有属性名
  • 值分为两种情况:
    • 直接映射:目标类型U中的属性名,且原始属性类型与目标属性类型完全匹配
    • 嵌套映射:数组[目标属性名, 子映射对象],仅当原始属性和目标属性均为对象类型时生效
type Mapping<T extends object, U extends object> = {
  [OriginalKey in keyof T]: 
    // 直接映射:匹配U中类型一致的属性名
    { [K in keyof U]: T[OriginalKey] extends U[K] ? K : never }[keyof U]
    // 嵌套映射:仅当原始属性和目标属性都是对象时允许
    | (T[OriginalKey] extends object ? 
        { [K in keyof U]: U[K] extends object ? [K, Mapping<T[OriginalKey], U[K]>] : never }[keyof U]
        : never);
};

2. 实现泛型convert函数

利用Mapping<T, U>约束参数,确保输入输出类型严格匹配,消除any:

function convert<T extends object, U extends object>(
  obj: T,
  mapping: Mapping<T, U>
): U {
  const ret = {} as U;

  // 断言entries类型为[keyof T, 对应映射值],确保类型安全
  for (const [originalKey, mappingValue] of Object.entries(mapping) as [keyof T, typeof mapping[keyof T]][]) {
    const originalValue = obj[originalKey];

    if (Array.isArray(mappingValue)) {
      // 处理嵌套映射
      const [newKey, subMapping] = mappingValue;
      ret[newKey] = convert(originalValue as Extract<T[keyof T], object>, subMapping) as U[keyof U];
    } else {
      // 处理直接映射
      const newKey = mappingValue as keyof U;
      ret[newKey] = originalValue as U[keyof U];
    }
  }

  return ret;
}

完整使用示例

interface AB {
    a: string;
    b: C;
}

interface C {
    c: number;
}

interface XY {
    x: string;
    y: Z;
}
interface Z {
    z: number;
}

const abc: AB = {
    a: '...',
    b: {
        c: 123,
    },
};

// 映射规则自动校验类型,不符合约束会报错
const ab_xy: Mapping<AB, XY> = {
    a: 'x',
    b: ['y', {
        c: 'z'
    }]
};

// 自动推导返回类型为XY,无需手动标注
const actual_xyz = convert(abc, ab_xy);
const expected_xyz: XY = {
    x: '...',
    y: {
        z: 123,
    }
};

console.log('         abc: %o', abc);
console.log('expected_xyz: %o', expected_xyz);
console.log('  actual_xyz: %o', actual_xyz);

关键特性

  • 类型安全:如果映射规则写错(比如把a映射到y),TypeScript会直接报错
  • 自动推导:调用convert时无需手动指定泛型参数,TypeScript会根据输入自动推导T和U
  • 支持嵌套:递归处理多层嵌套对象的映射

内容的提问来源于stack exchange,提问作者Vito De Tullio

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 07:07:07