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

TypeScript中WrongPick处理联合类型为何结果不符合预期?

为什么WrongPick处理联合类型参数时结果不符合预期?

先看示例代码:

interface Todo {
  title: string
  description: string
  completed: boolean
}

type WrongPick<T, K> =  K extends keyof T ? {[P in K]: T[P]} : never

type wrong_result = WrongPick<Todo, 'title' | 'completed'>
// expected: { title: string ; completed: boolean }
// actual: { title: string } | { completed: boolean }

type CorrectPick<T, K extends keyof T> = {[P in K]: T[P]}

type correct_result = CorrectPick<Todo, 'title' | 'completed'>
// expected: { title: string ; completed: boolean }
// actual: { title: string ; completed: boolean }

核心原因:分布式条件类型的触发

WrongPick的问题出在分布式条件类型的特性上:

  • 当泛型参数是裸类型参数(没有被数组、对象等包裹)且出现在extends关键字左侧时,TypeScript会自动将联合类型的每个成员单独代入条件判断,最后把所有分支的结果合并成新的联合类型。
  • 对于WrongPick<Todo, 'title' | 'completed'>,TypeScript会把联合类型拆成两个独立分支处理:
    1. 代入K='title':'title' extends keyof Todo成立,返回{ title: string }
    2. 代入K='completed':'completed' extends keyof Todo成立,返回{ completed: boolean }
      最终结果就是这两个对象类型的联合{ title: string } | { completed: boolean },和预期不符。

CorrectPick为什么能得到正确结果

CorrectPick把泛型参数K直接约束为K extends keyof T,此时在映射类型{[P in K]: T[P]}中:

  • K作为一个整体的联合类型被处理,不会触发分布式条件类型。
  • 映射类型会遍历联合类型中的每个成员,将它们全部添加到同一个对象类型中,最终生成包含所有指定属性的对象,符合预期。

额外修复方案:避免分布式行为

如果不想给K加约束,也可以通过把K包裹在数组或元组里,避免触发分布式条件类型:

type FixedWrongPick<T, K> = [K] extends [keyof T] ? {[P in K]: T[P]} : never
type fixed_result = FixedWrongPick<Todo, 'title' | 'completed'> // 得到{ title: string; completed: boolean }

这里[K]是一个包裹后的类型,不再是裸类型,所以不会拆分联合类型,而是把整个联合作为一个整体进行条件判断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 14:05:30