字符串字面量联合的分布式条件类型:参数同子联合类型需求问题
解决TypeScript联合类型参数的分组约束问题
你需要实现的是让函数的input和output参数同属一个预先定义的字面量分组(比如A组或B组),但当前代码因TypeScript的分布式条件类型特性,把每个字面量单独拆分处理了,导致结果不符合预期。
问题原因
当你使用T extends Union这种条件类型时,TypeScript会触发分布式条件类型:它会把联合类型的每个成员逐一传入条件类型进行计算,最终把结果重新合并成联合类型。所以params<Union>会把A | B拆成"A1" | "A2" | "A3" | "B1" | "B2" | "B3",每个字面量单独生成{input: T, output: T},就得到了所有单个字面量的成对组合。
解决方案
方案1:阻止分布式条件类型展开
通过把泛型参数包裹在元组中,避免TypeScript对联合类型进行拆分:
type A = "A1" | "A2" | "A3"; type B = "B1" | "B2" | "B3"; type Union = A | B; // 用元组[T]包裹,避免分布式展开 type Params<T> = [T] extends [Union] ? { input: T, output: T } : never; // 直接组合A和B对应的参数类型 type DesiredParams = Params<A> | Params<B>; function test(params: DesiredParams) { // 函数逻辑 }
方案2:直接定义期望的联合类型
如果分组数量固定,最直接的方式是直接写出你期望的联合类型:
type A = "A1" | "A2" | "A3"; type B = "B1" | "B2" | "B3"; // 直接定义允许的参数结构 type Params = { input: A, output: A } | { input: B, output: B }; function test(params: Params) { // 函数逻辑 }
方案3:通用泛型分组方案
如果需要更通用的写法,可以先定义分组类型,再组合成合法参数类型:
type GroupA = "A1" | "A2" | "A3"; type GroupB = "B1" | "B2" | "B3"; type AllGroups = GroupA | GroupB; // 泛型:接受一个分组类型,返回对应的参数结构 type Params<G extends AllGroups> = { input: G, output: G }; // 组合所有合法的分组参数类型 type ValidParams = Params<GroupA> | Params<GroupB>; function test(params: ValidParams) { // 函数逻辑 }
效果验证
以上方案都能让test函数接受的参数满足:
input和output必须属于同一分组(A或B)- 不允许跨组组合(比如
input: "A1"和output: "B1"会被类型检查拒绝)
内容的提问来源于stack exchange,提问作者Justin Henry
相关产品推荐
相关产品推荐

