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

TypeScript类型层面为何部分场景需NoInfer,部分场景却不需要?

TypeScript中IsAny约束的循环引用问题与NoInfer的作用解析

IsAny类型工具的标准定义

IsAny是判断类型是否为any的常用类型工具,标准实现如下:

type IsAny<T> = 0 extends 1 & T ? true : false;

未使用NoInfer时的循环引用错误

将IsAny用作类型参数的约束条件时,会触发循环引用错误:

type TShouldNotBeAny<T extends IsAny<T> extends true ? never : unknown> = T;
// 错误提示:Type parameter 'T' has a circular constraint.

添加NoInfer修复错误

在IsAny的定义中引入NoInfer<T>后,循环引用错误被修复,且约束逻辑正常生效:

type IsAny<T> = 0 extends 1 & NoInfer<T> ? true : false;

type TShouldNotBeAny<T extends IsAny<T> extends true ? never : unknown> = T; // 无错误

type T1 = TShouldNotBeAny<string>; // 允许通过
type T2 = TShouldNotBeAny<number>; // 允许通过

type T3 = TShouldNotBeAny<any>; // 符合预期:不允许通过,提示Type 'any' does not satisfy the constraint 'never'.

IsString场景无需NoInfer的对比

类似的IsString约束场景却不需要使用NoInfer,也不会出现循环引用错误:

type IsString<T> = T extends string ? true : false;

type TShouldNotBeString<T extends IsString<T> extends true ? never : unknown> = T; // 无错误

type T1 = TShouldNotBeString<number>; // 允许通过
type T2 = TShouldNotBeString<bigint>; // 允许通过
type T3 = TShouldNotBeString<string>; // 符合预期:不允许通过,提示Type 'string' does not satisfy the constraint 'never'.

疑问与分析

按常理推断:

  • IsAny场景中,T并非类型推断点,理论上NoInfer不应起作用
  • IsAny<T> extends true的逻辑应该能直接根据T的类型返回true/false,不会构成循环引用——只有当约束条件中出现T extends T这类逻辑时,才会触发循环引用,比如下面的例子:
type TShouldNotBeAny<T extends IsAny<T> extends true ? never : T> = T; // 依然报错
// 注意:这里用T代替了unknown

上述代码即便添加NoInfer也会报错,这符合预期。但为什么NoInfer在最初的IsAny约束场景中却能解决循环引用问题?


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.02 04:04:51