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

如何定义键映射到对应泛型的TypeScript类型?(含Diff场景)

解决方案:使用TypeScript映射类型实现动态键值类型匹配

核心原因

Record<K, V> 要求所有键对应的值类型必须统一为V,无法为每个键单独关联不同的泛型类型。要实现每个键K对应的值类型为SomeGeneric<K>的结构,必须使用TypeScript的映射类型(Mapped Types)——它允许遍历原类型的所有键,并为每个键单独定义值类型。

步骤1:定义Diff基础类型

先根据业务需求定义Diff<T>类型,比如存储新旧值的结构:

type Diff<T> = {
  old: T;
  new: T;
};

步骤2:创建通用的Changes映射类型

通过映射类型遍历目标类型的所有键,为每个键关联对应值类型的Diff:

type Changes<T> = {
  [K in keyof T]: Diff<T[K]>;
};
  • keyof T:获取原类型T的所有键的联合类型
  • [K in keyof T]:遍历每个键K
  • Diff<T[K]>:为当前键K指定值类型为原类型中该键对应值的Diff类型

步骤3:生成目标类型SprocketChanges

直接用通用类型传入Sprocket即可自动生成所需类型:

type SprocketChanges = Changes<Sprocket>;

完整示例代码

interface Sprocket {
  name: string;
  fobbed: boolean;
  cycles: number;
}

type Diff<T> = {
  old: T;
  new: T;
};

type Changes<T> = {
  [K in keyof T]: Diff<T[K]>;
};

type SprocketChanges = Changes<Sprocket>;

// 实例用法
const older: Sprocket = { name: 'Gizmo', fobbed: true, cycles: 12 };
const newer: Sprocket = { name: 'Gizmo', fobbed: false, cycles: 45 };

const sprocketDiff: SprocketChanges = {
  name: { old: older.name, new: newer.name },
  fobbed: { old: older.fobbed, new: newer.fobbed },
  cycles: { old: older.cycles, new: newer.cycles }
};

扩展:仅保留有变化的键

如果需要生成只包含实际变化键的类型,可以结合Partial:

type PartialChanges<T> = Partial<Changes<T>>;

// 用法:只需要填充有变化的键
const partialDiff: PartialChanges<Sprocket> = {
  fobbed: { old: true, new: false },
  cycles: { old: 12, new: 45 }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 04:55:21