Skip to main content

4260 - AllCombinations

Answer TestCases

实现类型 AllCombinations<S>,返回使用S中字符的所有组合字符串,每个字符最多只能使用一次。

例如:

type AllCombinations_ABC = AllCombinations<'ABC'>
// should be '' | 'A' | 'B' | 'C' | 'AB' | 'AC' | 'BA' | 'BC' | 'CA' | 'CB' | 'ABC' | 'ACB' | 'BAC' | 'BCA' | 'CAB' | 'CBA'

Solution

type AllCombinations<S extends string, U extends string = StringToUnion<S>> = [
U
] extends [never]
? ''
: '' | { [K in U]: `${K}${AllCombinations<never, Exclude<U, K>>}` }[U]

AllCombinations 接收两个泛型

  • S: 字符串
  • U: 默认为字符串中每个字符组成的联合类型, StringToUnion 来自于 531 题

如果 Unever 则返回空字符,否则将通过类型映射进行递归

下面以一个实际的例子介绍内部是如何运行的。假设字符串 S 等于 'AB'

U 等于 'A' | 'B'

在判断 never 的分支上不满足, 则进入另一个分支

{ [K in U]: `${K}${AllCombinations<never, Exclude<U, K>>}` }

映射类型 章节中, 我们知道, 当 in 后面是联合类型时, 则会对联合类型的各个子类型分别赋值给 K, 而 Exclude 则是将从联合类型中剔除特定的类型

此时该分支就变成了

{
'A': `A${AllCombinations<never, 'B'}`,
'B': `B${AllCombinations<never, 'A'}`,
}

AllCombinations<never, 'B'> 结果为

'' | 'B'

同理, 最后分支变为了

{
'A': `A${'' | 'B'}`,
'B': `B${'' | 'A'}`,
}

得到

{
'A': 'A' | 'AB',
'B': 'B' | 'BA',
}

在类型映射分支的最后加上 [U]

{
'A': 'A' | 'AB',
'B': 'B' | 'BA',
}['A' | 'B']

得到结果 'A' | 'AB' | 'B' | 'BA'

最后在联合上空字符, 即得到了最终结果。