如何定义键映射到对应泛型的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]:遍历每个键KDiff<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
相关产品推荐
相关产品推荐

