联合分散可化简

将联合类型的字符串_去点,并将_后的第一个字母大写

type CamelcaseUnion<Item extends string> = Item extends `${infer Left}_${infer Right}${infer Rest}` ?
  `${Left}${Uppercase<Right>}${CamelcaseUnion<Rest>}`
: Item;
type item = CamelcaseUnion<'aa_bb_cc_dd'>;

这样看来,对联合类型的操作和对单个字符串的操作一样。这就是联合分散可简化,这样看来是优点。但是再有写情况也增加了认知成本。

判断联合类型

type IsUnion<A,B = A> =
A extends A
  ? [B] extends [A]
    ? false
    : true
  : never

当输入联合类型的时候返回true,输入的不是联合类型的时候返回false。是不是看不懂?我也看不懂。我们先看下面的代码

type TestUnion<A, B = A> = A  extends A ? { a: A, b: B} : never;
type TestUnionResult = TestUnion<'a' | 'b' | 'c'>;

其中TestUnionResult的类型是

type TestUnionResult = {
    a: "a";
    b: "a" | "b" | "c";
} | {
    a: "b";
    b: "a" | "b" | "c";
} | {
    a: "c";
    b: "a" | "b" | "c";
}

因为条件类型中如果左边的类型是联合类型,会把每个元素单独传入做计算,而右边不会。所以A是’a’的时候,B是’a’|‘b’|‘c’。所以可以利用这个特点来判断是否是联合类型。所以就有了以上的代码

type IsUnion<A,B = A> =
A extends A
  ? [B] extends [A]
    ? false
    : true
  : never

BEM

BEM是css命名规范

type bemResult = BEM<'guang', ['aaa', 'bbb'], ['warning', 'success']>;
//会转换成
guang__aaa--warning guang__bbb--success

数组转换成联合类型可以这样写

type union = ['aaa', 'bbb'][number];
type BEM<
  Block extends string,
  Element extends string[],
  Modifiers extends string[]
> = `${Block}__${Element[number]}--${Modifiers[number]}`;
type bemResult = BEM<'guang', ['aaa', 'bbb'], ['warning', 'success']>;

AllCombinations

type Combination<A extends string, B extends string> =
    | A
    | B
    | `${A}${B}`
    | `${B}${A}`;
type AllCombinations<A extends string, B extends string = A> = 
A extends A
    ? Combination<A, AllCombinations<Exclude<B, A>>>
    : never;
type all = AllCombinations<'A' | 'B' | 'C'>;

参考资料

[1]TypeScript 类型体操通关秘籍