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

TypeScript中如何过滤联合类型内的反向重复二元组

解决方案

方案一:从生成逻辑避免反向重复(推荐)

直接调整配对生成逻辑,从根源上不会产生反向重复的配对,代码简洁且通用,支持任意长度的字符串字面量联合类型:

type Animal = "cat" | "dog" | "rabbit"

// 辅助工具:提取联合类型的第一个成员
type TakeFirst<U> = 
  (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;

// 通用工具:生成联合类型所有无反向重复的两两配对
type UniquePairs<U extends string> = 
  // 联合类型为空时终止递归
  [U] extends [never] ? never :
  // 取出当前联合的第一个成员
  TakeFirst<U> extends infer First extends string
  // 取出剩余的其他成员
  ? Exclude<U, First> extends infer Rest extends string
    // 生成当前成员和所有剩余成员的配对,再递归生成剩余成员之间的配对
    ? [First, Rest] | UniquePairs<Rest>
    : never
  : never;

type Pairs = UniquePairs<Animal>
// 最终类型:["cat", "dog"] | ["cat", "rabbit"] | ["dog", "rabbit"]

方案二:基于已有带重复的Pairs类型过滤

如果你需要保留原有生成逻辑,只对已经生成的带反向重复的Pairs类型做过滤,可以使用以下方案:

// 你的原有代码
type Animal = "cat" | "dog" | "rabbit"
type PairsMap = {
    [K1 in Animal]: {
        [K2 in Animal]: K1 extends K2 ? never : [K1, K2]
    }
}
type Values<T> = T[keyof T]
type Pairs = Values<Values<PairsMap>> 

// 过滤反向重复的工具类型
type FilterReversePairs<T extends [string, string]> = 
  T extends [infer A, infer B]
  ? `${A}` extends `${B}` ? never :
  `${A}` extends `${infer AChar}${infer ARest}` 
  ? `${B}` extends `${infer BChar}${infer BRest}`
    ? AChar extends BChar
      // 首字符相同则递归比较剩余字符
      ? FilterReversePairs<[ARest, BRest]> extends never ? never : T
      // 首字符不同则只保留首字符字典序更靠前的配对
      : `${AChar}${BChar}` extends `${BChar}${AChar}` ? never : `${AChar}` extends 'a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'|'i'|'j'|'k'|'l'|'m' ? BChar extends 'n'|'o'|'p'|'q'|'r'|'s'|'t'|'u'|'v'|'w'|'x'|'y'|'z' ? T : never : T
    : T
  : never;

type UniquePairs = FilterReversePairs<Pairs>
// 最终类型同样是["cat", "dog"] | ["cat", "rabbit"] | ["dog", "rabbit"]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 07:54:03