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

TypeScript如何实现将对象所有键拼接为指定分隔符的联合类型?

TypeScript如何实现将对象所有键拼接为指定分隔符的联合类型?

嘿,这个需求其实可以通过TypeScript的条件类型和字符串模板类型来实现,咱们一步步来拆解~

首先看你的基础场景:对象只有两个键的情况,其实可以用嵌套的映射类型快速实现:

type MyObject = {
  one: string;
  two: string;
};

// 针对两个键的精简版本
type Concatenator<T extends Record<string, string>, S extends string = '/'> = {
  [K1 in keyof T]: {
    [K2 in Exclude<keyof T, K1>]: `${K1}${S}${K2}`
  }[Exclude<keyof T, K1>]
}[keyof T];

// 测试完全符合你的要求
const concatenated1: Concatenator<MyObject> = 'one/two'; // 合法
const concatenated2: Concatenator<MyObject> = 'two/one'; // 合法
// 输入不符合的字符串会直接报错,比如'one/one'或者'three/four'

这个思路特别直接:先遍历第一个键K1,再遍历排除K1后的剩余键K2,把它们用指定分隔符拼接起来,最后取所有可能结果的联合类型,刚好覆盖两种排列顺序。

但如果你的对象可能有更多键(比如3个、4个),上面的写法就不够通用了,这时候咱们可以写一个能处理任意数量字符串键的通用版本:

// 辅助类型:计算联合类型的元素个数
type LengthOfUnion<T> = 
  T extends never ? 0 :
  (T extends infer U ? (U extends T ? 1 + LengthOfUnion<Exclude<T, U>> : 0) : 0);

// 辅助类型:将字符串数组用分隔符拼接成单个字符串
type JoinKeys<Keys extends string[], Separator extends string> = 
  Keys extends [infer First extends string, ...infer Rest extends string[]]
    ? Rest extends []
      ? First
      : `${First}${Separator}${JoinKeys<Rest, Separator>}`
    : never;

// 辅助类型:生成所有键的排列组合并拼接
type PermuteAndJoin<T extends string, Separator extends string, Accumulated extends string[] = []> = 
  // 当积累的键数量等于原联合类型长度时,拼接成结果
  LengthOfUnion<T> extends [...Accumulated, string]['length']
    ? JoinKeys<Accumulated, Separator>
    : // 否则递归遍历剩余的键,生成所有排列
      T extends infer U ? U extends string
        ? PermuteAndJoin<Exclude<T, U>, Separator, [...Accumulated, U]>
        : never
      : never;

// 最终的通用Concatenator类型
type Concatenator<T extends Record<string, string>, S extends string = '/'> = 
  PermuteAndJoin<keyof T & string, S>;

// 测试多键场景
type MyObject3 = {a: string; b: string; c: string};
const concatenated3: Concatenator<MyObject3> = 'a/b/c'; // 合法
const concatenated4: Concatenator<MyObject3> = 'b/c/a'; // 合法
const concatenated5: Concatenator<MyObject3> = 'c/a/b'; // 合法
// 不符合全键排列的字符串会报错

这个通用版本的核心逻辑是:

  1. 先通过LengthOfUnion计算对象键的总数量,用来判断是否已经收集完所有键
  2. JoinKeys递归把排列好的键数组用分隔符拼接成字符串
  3. PermuteAndJoin递归遍历所有可能的键排列,当收集到所有键时,就生成对应的拼接字符串,最终所有结果组成联合类型

这样不管你的对象有多少个字符串键,都能生成所有可能的键排列拼接结果,而且分隔符支持自定义(默认是/,你也可以改成-、_这类符号)。

备注:内容来源于stack exchange,提问作者MGX

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 09:23:01