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

TypeScript递归类型函数错误返回never类型问题排查

问题分析与修正方案

是的,你写的这个Wow递归类型确实会返回never,但原因和你描述的略有不同——不是因为单元素数组时递归分支返回never,而是多次交叉带有同名value属性的对象时,不同字符串字面量类型的value会交叉出never类型。

具体逻辑链:

  • 处理Wow<['d']>时,结果是{value: 'd'} & {},也就是{value: 'd'},这一步正常。
  • 处理Wow<['c','d']>时,会变成{value: 'd'} & {value: 'c'},此时value的类型是'd' & 'c'——不同字符串字面量没有交集,结果为never,整个对象类型也就等价于never。
  • 再往上递归,所有包含这个never的交叉类型都会直接变成never,最终Wow<['a','b','c','d']>的结果自然是never。

修正方案1:返回包含所有可能value的联合类型对象

如果目标是得到所有元素对应的{value: 元素}的联合,把交叉&改成联合|即可:

import { List } from "ts-toolbelt";

type Wow<TArr extends string[]> = TArr['length'] extends 0
  ? {}
  : {
    value: List.Last<TArr>
  } | Wow<List.Pop<TArr>>;

type a = Wow<['a', 'b', 'c', 'd']>;
// 类型为 { value: 'a' } | { value: 'b' } | { value: 'c' } | { value: 'd' }

修正方案2:生成嵌套结构

如果想要层级嵌套的对象(每个节点包含当前元素和下一层节点),调整为带next属性的嵌套类型:

import { List } from "ts-toolbelt";

type Wow<TArr extends string[]> = TArr['length'] extends 0
  ? undefined
  : {
    value: List.Last<TArr>,
    next: Wow<List.Pop<TArr>>
  };

type a = Wow<['a', 'b', 'c', 'd']>;
// 类型为 { value: 'd'; next: { value: 'c'; next: { value: 'b'; next: { value: 'a'; next: undefined } } } }

修正方案3:单value属性包含所有元素的联合

如果希望最终对象只有一个value属性,类型是数组所有元素的联合,直接用Union.ListOf提取联合类型即可,无需递归交叉:

import { List, Union } from "ts-toolbelt";

type Wow<TArr extends string[]> = {
  value: Union.ListOf<TArr>
};

type a = Wow<['a', 'b', 'c', 'd']>;
// 类型为 { value: 'a' | 'b' | 'c' | 'd' }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 13:50:26