如何创建可自动推断对象字段的TypeScript泛型类型
解决方案
要实现自动推断字段对应的类型,同时强制数组包含目标对象的所有字段,可以通过映射类型生成字段工厂项的联合类型,再结合类型约束确保所有字段被覆盖,无需手动传入字段参数。
实现代码
// 单个字段的工厂项类型:自动映射每个key对应的value类型 type FactoryItem<TObj> = { [K in keyof TObj]: { field: K; // 自动推断value为对应字段的类型,obj为整个目标对象类型 factory: (value: TObj[K], obj: TObj) => any; }; }[keyof TObj]; // 核心类型:要求数组包含所有字段的工厂项 type MyMagicType<TObj> = FactoryItem<TObj>[] & { // 类型约束:若数组遗漏字段,此条件不成立,触发类型错误 _ensureAllFields: keyof TObj extends (this[number]['field']) ? unknown : never; }; // 辅助函数(可选,用于更友好的类型推断和报错提示) function createFactory<TObj>(items: MyMagicType<TObj>) { return items; }
使用示例
type Row = { foo: string; bar: number; baz: unknown; }; // ❌ 报错:缺少baz字段,类型不匹配 const incompleteFactory = createFactory<Row>([ { field: 'foo', factory: (value, obj) => value.toUpperCase() }, { field: 'bar', factory: (value, obj) => value + 1 }, ]); // ✅ 正确:包含所有字段,每个factory的value类型自动推断 const completeFactory = createFactory<Row>([ { field: 'foo', factory: (value, obj) => value.toUpperCase() }, // value: string { field: 'bar', factory: (value, obj) => value + 1 }, // value: number { field: 'baz', factory: (value, obj) => value }, // value: unknown ]);
原理说明
- 自动推断类型:通过
[K in keyof TObj]遍历目标对象的所有键,为每个键生成对应的工厂项类型,factory的第一个参数会自动绑定为该键的类型。 - 强制字段完整性:
_ensureAllFields的条件判断会检查数组中所有field的联合是否覆盖了keyof TObj,若遗漏字段,TypeScript会直接抛出类型错误。 - 无需手动传字段参数:整个类型仅需传入目标对象
TObj,所有字段的类型推导和约束都自动完成,不用额外指定字段参数。
内容的提问来源于stack exchange,提问作者plusheen
相关产品推荐
相关产品推荐

