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

TypeScript中NoInfer类型未按预期工作的问题咨询

TypeScript类型推断失败原因分析

问题代码

以下代码中,编译器无法正确推断泛型T的类型,导致state和inferred都被标记为unknown:

function inferTest<T>(factory: (setter: (setterFn: (arg: NoInfer<T>) => NoInfer<T>) => void) => T) {
    return factory(null!);
}
const inferred = inferTest((setter) => ({
    count: 0,
    increment: () => setter(state => ({ count: state.count + 1 })) // 'state' is of type 'unknown'.
}));
console.log(inferred.count); // 'inferred' is of type 'unknown'.

期望与实际结果

期望T被推断为:

{
    count: number,
    increment: () => void,
}

但实际编译器将T设为unknown,触发两个编译错误:

'state' is of type 'unknown'.
'inferred' is of type 'unknown'.

移除increment属性后,代码可正常工作,T被正确推断为{count: number}:

function inferTest<T>(factory: (setter: (setterFn: (arg: NoInfer<T>) => NoInfer<T>) => void) => T) {
    return factory(null!);
}
const inferred = inferTest(() => ({
    count: 0
}));
console.log(inferred.count);

原因解析

核心问题在于类型推断的循环依赖:

  1. 泛型T的类型本应从factory函数的返回值推断而来,也就是你定义的包含count和increment的对象。
  2. 但increment的实现中调用了setter,而setter接收的setterFn参数要求输入NoInfer<T>类型的state——这里的NoInfer<T>只是告诉编译器“不要从这个位置反向推断T”,但并没有解决T本身的定义依赖于increment内部对T的引用。
  3. 此时形成了闭环:T的完整类型需要increment的类型,而increment的类型又需要知道T是什么才能确定state的类型。TypeScript无法解开这个循环,只能将T默认设为unknown。

当移除increment后,factory的返回值是明确的{count: number},没有依赖T的其他部分,编译器可以直接推断出T的类型,自然不会出现错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 23:47:35