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

TypeScript泛型箭头函数结合extends的类型定义工作原理

MyEqual 类型工作原理解析

这是TypeScript类型编程中实现严格类型相等判断的经典实现,你提到的infer并没有在这段代码里出现,整个逻辑完全围绕extends关键字的两类不同运行规则展开。

两层extends的不同逻辑

代码中一共出现两处extends,作用完全不同:

  • 内层的T extends X ? 1 : 2、T extends Y ? 1 : 2属于普通条件类型:逻辑很直白,当类型T可赋值给extends右侧的类型时,返回字面量类型1,否则返回2。
  • 外层的(<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2)是泛型函数类型的兼容性校验,这才是实现相等判断的核心。

泛型函数校验的特殊规则

TS在判断两个带泛型的无参函数类型是否满足extends(即是否可以互相赋值)时,不会直接对比泛型声明,而是会在类型系统内部生成一个全局唯一、无任何额外约束的虚拟类型,把这个虚拟类型代入两边的泛型参数T,再对比替换后两个函数的返回值是否完全一致:

  • 如果虚拟类型代入后,两边返回值完全相同,就判定两个泛型函数类型兼容,整个条件类型返回true
  • 如果返回值不同,就判定不兼容,返回false

为什么能做到严格相等

普通的双向extends判断(即先判断X extends Y再判断Y extends X)只能校验两个类型是否可互相赋值,会把any和任意类型、带可选属性的父类型和子类型误判为相等,但这个实现不会:

  • 当X和Y完全是同一个类型时,不管代入的T是什么类型,T extends X和T extends Y的判断结果永远一致,两边函数的返回值永远相同,因此函数类型兼容,返回true
  • 只要X和Y存在哪怕一点差异,TS生成的虚拟类型就会命中这个差异:要么T extends X成立但T extends Y不成立,要么反过来,导致两边返回值一个是1一个是2,函数类型不兼容,返回false

几个常见场景的运行结果:

  • MyEqual<boolean, boolean> → true
  • MyEqual<boolean, true | false> → true(二者在TS中是同一个类型)
  • MyEqual<any, string> → false(普通双向extends会误判为true)
  • MyEqual<{id: number}, {id: number, name?: string}> → false(普通双向extends会误判为true)

注:这个实现依赖TS内部的类型检查逻辑,属于官方文档没有明确说明的行为,存在大版本更新后失效的可能,但从TS 2.x到当前5.x的所有正式版本中都可以正常工作。

内容的提问来源于stack exchange,提问作者Daniel Rodríguez Meza

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 00:01:07