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

TypeScript创建映射类型时ReturnType失效?RawPerson推导为unknown问题

类型推导异常的核心原因
  • 泛型作用域遮蔽是头号诱因
    你当前的all实现存在关键的泛型冲突:外层函数声明了泛型<T>,用于接收调用时传入的具体类型(比如number、string);但返回的内层箭头函数前,你又重复声明了一个同名的<T>。TS的泛型是块级作用域的,这个内层的同名T会完全遮蔽外层的T,和你调用all时传入的类型没有任何关联。最终返回的是一个完全独立、未绑定任何具体类型的泛型函数,TS在没有上下文指定这个内层T的类型时,会默认将其推导为unknown。
  • Struct接口定义与实际返回值不匹配
    你定义的Struct索引签名要求每个字段都是可独立接收泛型参数的函数<T>(input: string) => T | DiplomacyError>,而非绑定了具体返回类型的普通函数。这种定义下,TS会认为每个字段的返回类型取决于调用时临时传入的泛型参数,没有固定的确定值。
  • ReturnType的提取逻辑限制
    ReturnType是基于函数已实例化、确定的返回值标注提取类型的。如果传入ReturnType的是未绑定泛型参数的泛型函数类型,TS没有足够的信息推导泛型对应的真实类型,最终只能返回unknown,这也是你看到推导结果全是unknown的直接表现。
修复方案

按以下步骤调整即可恢复预期的类型推导效果:

  1. 修正all函数的泛型声明
    删除内层返回函数前重复声明的<T>,直接复用外层已经绑定的泛型T,修改后的实现如下:
    export const all = <T>(typifier: Typifier<T>, ...assertions: Assertor[]) => 
      // 去掉此处冗余的<T>声明,直接使用外层的T作为返回值的类型标注
      (input: string): T | DiplomacyError => {
        const parsedInput = typifier(input);
        if (parsedInput === "#!CD") {
          return "#!CD" as DiplomacyError;
        }
        for (let i = 0; i < assertions.length; i++) {
          if (assertions[i](parsedInput) === "#!CD") {
            return "#!CD" as DiplomacyError;
          }
        }
        // 类型匹配后无需双重断言,直接返回即可
        return parsedInput;
      };
    
    调整后,当你调用all<number>(isInteger, isNonNegative)时,得到的是一个完全固定了T为number的普通函数,类型为(input: string) => number | DiplomacyError,不再是待实例化的泛型函数。
  2. 调整Struct接口的定义
    移除索引签名中函数的冗余泛型参数,匹配修改后的返回函数类型:
    export interface Struct {
      // 去掉函数前的<T>,每个字段为已绑定返回类型的普通函数
      [key: string]: (input: string) => unknown;
    }
    
  3. 最终推导效果
    完成上述修改后,Person对象的字段类型为:
    • age: (input: string) => number | DiplomacyError
    • name: (input: string) => string | DiplomacyError
      此时RawType<typeof Person>会正确推导出你预期的RawPerson结构:
    type RawPerson = {
      age: number | DiplomacyError,
      name: string | DiplomacyError
    }
    

内容的提问来源于stack exchange,提问作者Davide Valdo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.26 07:45:00