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

如何实现createFieldGroup函数基于asString属性的返回值类型推导?

如何实现createFieldGroup函数基于asString属性的返回值类型推导?

我明白你的问题了——你需要让createFieldGroup的返回类型根据每个字段的asString属性动态决定是原类型还是string,同时还要保证validator的参数类型能正确推断自value。之前的思路卡在了如何单独提取每个字段的asString字面量类型,其实我们可以通过基于输入类型的映射转换来解决这个问题,不需要复杂的多类型参数推断。

具体实现步骤:

  1. 重新定义FieldSpec,明确字面量类型的默认值
    先把asString的类型约束为布尔字面量,并给它一个默认值false,这样当用户不传入asString时,默认保持原类型:

    type FieldSpec<T, AsString extends boolean = false> = {
      value: T;
      asString?: AsString;
      validator?: (v: T) => void;
    };
    
  2. 定义返回类型的转换助手
    用一个助手类型来单独处理每个字段的返回类型,判断asString是否为true字面量,是的话返回string,否则返回原value的类型:

    type FieldGroupReturn<Fields extends Record<string, FieldSpec<any, any>>> = {
      [K in keyof Fields]: Fields[K]['asString'] extends true 
        ? string 
        : Fields[K]['value'];
    };
    
  3. 调整createFieldGroup的类型声明
    让函数直接推断输入的fields的类型,然后用上面的助手类型生成返回类型:

    declare function createFieldGroup<F extends Record<string, FieldSpec<any, any>>>(
      fields: F
    ): FieldGroupReturn<F>;
    

验证你的示例场景

现在测试你给出的例子,完全符合预期:

const x = createFieldGroup({
  foo: { value: true, asString: true, validator(v) {
    // v的类型自动推断为boolean ✅
  } },
  bar: { value: 0, asString: false, validator(v) {
    // v的类型自动推断为number ✅
  } }
});
// x的类型自动推断为 { foo: string; bar: number } ✅

处理asString未传入的情况

如果某个字段省略了asString,会默认使用false,返回原value的类型:

const y = createFieldGroup({
  baz: { value: 'hello', validator(v) {
    // v的类型自动推断为string ✅
  } }
});
// y的类型自动推断为 { baz: string } ✅

为什么之前的思路有问题?

你之前尝试用两个类型参数T和U分别推断value和asString,但TypeScript的类型推断很难同时对齐两个独立的Record类型的key。而直接基于输入的fields类型做映射转换,能更精准地提取每个字段的asString和value的字面量类型,避免了多参数推断的对齐问题。

另外,你尝试重构FieldSpec让它依赖一个包含value和asString的泛型参数,这种方式会破坏TypeScript的类型推断优先级——因为TypeScript更倾向于从最外层的类型参数开始推断,而不是嵌套的属性类型,所以这种方案的推断效果会变差。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 12:04:32