TypeScript实现generateControlsAccessObject简化校验控制对象初始化
实现方案
该需求可以实现,核心思路是通过泛型约束+映射类型,为返回对象的每个属性单独推导对应的类型约束。
第一步:定义工具类型
先写两个工具类型,从ValidatableControlPayload中提取出对应的ValidValue和InvalidValue泛型参数:
// 补充缺失的基础类型定义(原代码未给出,不影响核心逻辑) type ValidatableControl = unknown; // 提取ValidatableControlPayload的ValidValue泛型参数 type ExtractValidValue<T extends ValidatableControlPayload<any, any>> = T extends ValidatableControlPayload<infer V, any> ? V : never; // 提取ValidatableControlPayload的InvalidValue泛型参数 type ExtractInvalidValue<T extends ValidatableControlPayload<any, any>> = T extends ValidatableControlPayload<any, infer I> ? I : never;
第二步:实现generateControlsAccessObject函数
泛型直接接收目标返回对象的类型,通过映射类型为每个属性单独约束initialValue的允许类型:
function generateControlsAccessObject<T extends Record<string, ValidatableControlPayload<any, any>>>( initialData: { [K in keyof T]: { initialValue: ExtractValidValue<T[K]> | ExtractInvalidValue<T[K]> } } ): T { const accumulatingControlAccess: Record<string, any> = {}; for (const [key, data] of Object.entries(initialData)) { accumulatingControlAccess[key] = generateInitialValidatableControlPayload(data); } return accumulatingControlAccess as T; }
效果验证
实现后完全符合类型校验要求:
type ControlsAccess = { age: ValidatableControlPayload<number, null>; prefecture: ValidatableControlPayload<string, null>; }; // 正常通过类型校验 const controlsAccess: ControlsAccess = generateControlsAccessObject({ age: { initialValue: null }, prefecture: { initialValue: "tokyo" } }); // 会抛出TypeScript错误:age的initialValue不能为string类型 const invalidControls: ControlsAccess = generateControlsAccessObject({ age: { initialValue: "18" }, prefecture: { initialValue: null } });
内容的提问来源于stack exchange,提问作者Takeshi Tokugawa YD
相关产品推荐
相关产品推荐

