Typescript infer 和 never 一起用,结果不同

极简的 demo 如下:

Question1: 为什么 type g2 而不是 1?

// 1
type f = [never] extends [infer S1, ...infer S2]
  ? ([S1] extends [never] ? 1 : 2)
  : 3
// why 2
type g = [never] extends [infer S1, ...infer S2]
  ? ([never] extends [S1] ? 1 : 2)
  : 3

按我理解,type fg 相等,因为 S1never.

Question2: 为什么 h2 不是 1?

// 1
type i = [never] extends [infer S1]
  ? ([never] extends [S1] ? 1 : 2)
  : 3
// why 2
type h = [never] extends [infer S1, ...infer S2]
  ? ([never] extends [S1] ? 1 : 2)
  : 3

按我理解, type ih 相等,因为 S2 没用.

Question3: 为什么 type knever?

// 1
type j = [never] extends [infer S1, ...infer S2]
  ? (never extends S1 ? 1 : 2)
  : 3
// why never ?
type k = [never] extends [infer S1, ...infer S2]
  ? (S1 extends never ? 1 : 2)
  : 3

我以为 k 应该是 1 2 3 其中一个.

阅读 1.7k
1 个回答

谢邀,没搞过太复杂的类型,试了好久,好像被我试出原因了 🤣

排除意外,把你的问题精简,最简形式

type a = [never] extends [infer S1] // S1 应该是 never ,所以不可能返回3 吧
  ? (S1 extends never ? 1 : 2)
  : 3

应该返回 1 吧, 不能是 2 吧?

让我惊掉下巴的 a 居然是 never

这条语句无论如何不可能返回 never 啊,抛出异常了还是咋的?

(S1 extends never ? 1 : 2)

我觉得应该是这条语句出bug了 ,

为啥会出 bug 呢,经过我一个多小时的研究。。。。

原因居然是。。。。。。。。

先点个赞吧。。。

infer 出来的 S1 ,并不是单纯的 never , 要用 NonNullable 处理一下,就正确了。

// 返回 1
type a2 = [never] extends [infer S1]
  ? (NonNullable<S1> extends never ? 1 : 2)
  : 3

同理把你的3个问题 infer 推导出来的类型,全都加上 NonNullable 就正确了


问题1

// 1
type g = [never] extends [infer S1, ...infer S2]
  ? ([never] extends NonNullable<[S1]> ? 1 : 2)
  : 3

问题2

// 1
type h = [never] extends [infer S1, ...infer S2]
  ? ([never] extends NonNullable<[S1]> ? 1 : 2)
  : 3

问题3

// 1
type k = [never] extends [infer S1, ...infer S2]
  ? (NonNullable<S1> extends never ? 1 : 2)
  : 3
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进