如何强制PatchOperation<Parent>的value与path指定类型匹配?
如何让PatchOperation的value与path指定的字段类型严格匹配?
你的问题核心是要让PatchOperation<T>的value类型和path指定的T字段类型做强绑定,避免出现path指向Date类型字段但value传字符串的情况。
原来的定义里,path是keyof T,value是T[keyof T]——这意味着value可以是T任意字段的类型,完全不跟path做关联,所以TypeScript没法帮你做类型校验。要解决这个问题,我们需要把PatchOperation定义成基于T每个键的联合类型,让每个联合成员里的path和value一一对应。
解决方案代码
首先,先确保你已经定义了OperationType(比如常见的JSON Patch操作类型):
type OperationType = 'Replace' | 'Add' | 'Remove' | 'Move' | 'Copy' | 'Test';
然后重新定义PatchOperation:
type PatchOperation<T> = { [K in keyof T]: { from?: keyof T; // 如果需要`from`也和特定字段关联,可以调整约束,这里保持原定义逻辑 op: OperationType; path: K; value?: T[K]; }; }[keyof T];
原理说明
这个定义的思路是:
- 用映射类型遍历
T的每个键K - 为每个
K生成一个对象类型,其中path被固定为K,value被固定为T[K](也就是K对应字段的类型) - 最后通过
[keyof T]把所有生成的对象类型合并成一个联合类型
这样当你创建PatchOperation<Parent>实例时,TypeScript会根据你指定的path自动推断value的类型:
测试你的示例
interface Parent { creation: Date; id: number; name: string; } // 这里会触发预期的类型错误:Type 'string' is not assignable to type 'Date | undefined' const update: PatchOperation<Parent> = { op: 'Replace', path: 'creation', value: 'string', };
如果传正确的类型就完全合法:
const validUpdate: PatchOperation<Parent> = { op: 'Replace', path: 'creation', value: new Date(), };
扩展说明
如果需要from字段也和path指向的字段类型关联(比如from只能指向和path同类型的字段),可以进一步调整映射类型:
type PatchOperation<T> = { [K in keyof T]: { from?: { [P in keyof T]: T[P] extends T[K] ? P : never }[keyof T]; op: OperationType; path: K; value?: T[K]; }; }[keyof T];
不过这属于额外需求,根据你的原问题,基础版本已经足够解决类型匹配的核心问题。
内容的提问来源于stack exchange,提问作者Alex Parloti
相关产品推荐
相关产品推荐

