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

TypeScript中Extend异常行为及Effect Ts类型逻辑疑问

关于Effect Ts中类型定义的疑问

问题背景

我在使用Effect Ts库时,遇到一段难以理解的类型定义:

export declare const typeSymbol: unique symbol
export type typeSymbol = typeof typeSymbol
type FilterIn<A> = A extends any ? typeSymbol extends keyof A ? A : never : never
type FilterOut<A> = A extends any ? typeSymbol extends keyof A ? never : A : never

疑问1:A extends any的分支作用是什么?

我测试了所有常见类型,包括never、unknown、void等,都没有找到会让A extends any条件为false的情况:

type t1 = undefined extends any ? 1 : 0 // 结果:1
type t2 = void extends any ? 1 : 0 // 结果:1
type t3 = null extends any ? 1 : 0 // 结果:1
type t4 = never extends any ? 1 : 0 // 结果:1
type t5 = unknown extends any ? 1 : 0 // 结果:1
type t6 = Function extends any ? 1 : 0 // 结果:1
type t7 = object extends any ? 1 : 0 // 结果:1

解答

确实不存在任何类型能让A extends any的条件为false,因为any是TypeScript的顶级类型,所有类型都可以赋值给any。这里使用A extends any的核心目的是触发分布式条件类型。

当泛型参数A是联合类型时,分布式条件类型会自动将联合类型拆分为单个成员,分别代入条件进行计算,最后把结果重新合并为联合类型。举个例子:
如果A是{ [typeSymbol]: number } | string | boolean,FilterIn<A>会分别对每个成员判断:

  • { [typeSymbol]: number }:满足typeSymbol extends keyof A,保留该类型
  • string:不满足,返回never
  • boolean:不满足,返回never
    最终FilterIn<A>的结果是{ [typeSymbol]: number }。

如果去掉A extends any的外层条件,直接写typeSymbol extends keyof A ? A : never,当A是联合类型时,整个条件会被当作一个整体判断,无法实现拆分筛选的效果。

疑问2:为什么K<never>返回never而非1?

我发现一个奇怪的现象:

type t = never extends any ? 1 : 0 // 结果:1
type K<A> = A extends any ? 1 : 0
type u = K<never> // 结果:never

解答

这是分布式条件类型的特殊规则导致的:当泛型参数传入never时,分布式条件类型会直接返回never。

  • 直接写never extends any ? 1 : 0不属于分布式条件类型(没有泛型参数的分发逻辑),所以TypeScript会正常判断never extends any为true,返回1。
  • 而K<never>中,A extends any触发了分布式条件类型,但never是一个空的联合类型,没有任何成员可以分发,因此整个类型计算直接返回never。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 14:03:20