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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 18:15:01