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

TypeScript递归类型实例化过深问题的深层原因探究

TypeScript递归类型的深层实例化报错解析疑惑

初始报错场景

以下代码会触发「类型实例化过深」的报错:

type Type = [unknown] & { type: unknown };

interface $Zeros extends Type {
//        ~~~~~~
// Type instantiation is excessively deep...
    type: Zeros<this[0]>
}

type Zeros<N, R extends unknown[] = []> =
    N extends R['length'] ? R : Zeros<N, [0, ...R]>;

我原本推测问题出在this[0]为unknown时,TS尝试展开Zeros<unknown>,因条件类型的写法陷入无限递归。将条件判断翻转后报错消失,验证了这一点:

// 此实现无报错
type Zeros<N, R extends unknown[] = []> =
    R['length'] extends N ? R : Zeros<N, [0, ...R]>;

修改Type定义后的异常表现

但将Type改为对象形式的定义后,报错直接消失:

type Type = { 0: unknown, type: unknown }

甚至直接交叉类型查询也能正常工作:

type GetZeros = ($Zeros & [3])['type']; // 正常解析为[0,0,0]

提取apply类型后的复现问题

然而把逻辑提取到apply类型后,相同的报错又出现了(同样可通过翻转Zeros的条件解决):

type apply<$T extends Type, Args> = ($T & Args)['type'];

type applyZeros = apply<$Zeros, [3]>;
//                ~~~~~~~~~~~~~~~~~~
// Type instantiation is excessively deep...

这里我感到困惑:原本以为this[0]会被推断为3,Zeros传入3后不会触发无限递归,但实际并非如此。显然我的认知模型存在偏差,想知道这背后的具体原因。

补充背景

以上是我在某个类型工具库中试验的两种简化设计。{ 0: unknown, type: unknown }的实现优势更多,是当前在用的方案,但[unknown] & { type: unknown }的报错行为更便于用户快速定位问题。在库的正常使用中,即使未传入参数,$Zeros['type']也会被其他类型查询以检查可组合性,因此处理this[0]为unknown时的无限递归问题至关重要。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 19:20:17