摘要
文章阐述 TypeScript 5.2 的类型参数占位符特性,其通过下划线让 TS 推断类型解决部分类型推断问题,还介绍了相关问题背景、争议和未来计划。
一、问题背景
在 TypeScript 中存在部分类型推断的问题。例如有一个makeSelectors
函数,它接受TSource
和TSelectors
两个类型参数。当只传入一个类型参数时,TypeScript 会报错提示缺少第二个类型参数,如const selectors = makeSelectors<{ id: number }>({...})
会提示“Expected 2 type arguments, but got 1”等错误。而如果传入第二个类型参数,又会导致大量重复代码,像const selectors = makeSelectors<{ id: number }, {...}>({...})
。TypeScript 团队领导 Ryan Cavanaugh 表示这种不能推断第二个类型参数的行为并非本意,是当时泛型实现方式的副作用。
二、解决方案:类型参数占位符
TypeScript 5.2 中的解决方案是“类型参数占位符”。可以在第二个类型参数位置传入下划线_
,TypeScript 就会自动推断类型,例如const selectors = makeSelectors<{ id: number }, _>({...})
,之后使用selectors.id({ id: 1 });
能得到正确的number
类型结果。这相比手动指定类型是一个很大的改进。
三、争议
这种方法存在争议。来自 Redux、React Query、XState 和 ArkType 的开源维护者都表达了类似的担忧,即把传入占位符的责任推给了函数使用者。例如 XState 的维护者 Mateusz Burzy ń ski 表示有些类型参数本不应手动提供,虽然可以要求用户使用_
,但感觉这是一件麻烦事。
四、未来计划
TypeScript 目前的计划是先推出类型参数占位符,之后再尝试自动推断。如该特性 PR 的作者 Wes Wigham 所说,先推出这个特性看看使用F<A,_,_>()
代替F<A>()
是否真的有足够大的差异来决定是否需要进一步改进。所以目前类型参数占位符是解决这个问题的最佳方案,但未来可能会重新审视。