※配列をソートした結果 ではなく 含まれている型をソートした結果を取得する方法です。
やりたいことの前準備で必要だったので、備忘録です。
// この型に文字列リテラルの配列を渡すと、ソートした結果の配列型を返す
type Sort<T extends string[]> = Joins<SortImpl<Separators<T>>>;
type Test = Sort<['AB', 'G', 'AE', 'G', 'BD', '2F', 'AC', 'B', '1F']>;
//=> type Test = ["AB", "AC", "AE", "B", "BD", "G", "G", "1F", "2F"]
// 対象となる文字とその並び順
type Characters = [
'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y',
'Z',
0, 1, 2, 3, 4,
5, 6, 7, 8, 9,
];
type Character = Characters[number];
// ソートするために文字列を文字単位に区切る
type Separator<T extends string> = T extends `${infer A extends Character}${infer B}` ? [A, ...Separator<B> ] : [];
type Separators<T extends string[]> = T extends [infer A extends string, ...infer B extends string[]] ? [Separator<A>, ...Separators<B>]: [];
// 区切った文字の復元用
type Join<T extends Character[]> = T extends [infer A extends Character, ...infer B extends Character[]] ? `${A}${Join<B>}` : '';
type Joins<T extends (Character[] | undefined)[]> = T extends [infer A extends Character[], ...infer B extends Character[][]] ? [Join<A>, ...Joins<B>] : [];
type Pop<T extends Character[]> = T extends [T[0], ...infer A] ? A : [];
// 対象となる文字を先頭から比較していき、どちらかがマッチするか調べる。
// どちらも引っかからない場合、次の対象文字で比較する。
// 同じ文字同士の場合、次の文字同士で比較する。
type Compare<T1 extends Character[], T2 extends Character[], C extends Character[] = Characters> =
T1[0] extends T2[0]
? [T1[0], T2[0]] extends [undefined, undefined]
? 0
: Compare<Pop<T1>, Pop<T2>>
: T1[0] extends undefined
? -1
: T2[0] extends undefined
? 1
: T1[0] extends C[0]
? -1
: T2[0] extends C[0]
? 1
: Compare<T1, T2, Pop<C>>;
// マージソートを行う
type Merge<T1 extends Character[][], T2 extends Character[][]> =
T1[0] extends undefined
? [...T2]
: T2[0] extends undefined
? [...T1]
: Compare<T1[0], T2[0]> extends -1
? T1 extends [infer A extends Character[], ...infer B extends Character[][]]
? [A, ...Merge<B, T2>]
: []
: T2 extends [infer A extends Character[], ... infer B extends Character[][]]
? [A, ...Merge<T1, B>]
: []
;
type SortImpl<T extends Character[][]> =
T[1] extends undefined
? [T[0]]
: T extends [infer A extends Character[], ...infer B extends Character[][]]
? Merge<[A], SortImpl<B>>
: [];