Unique
Challenge
Implement the type version of Lodash.uniq, Unique
type Res = Unique<[1, 1, 2, 2, 3, 3]>; // expected to be [1, 2, 3]
type Res1 = Unique<[1, 2, 3, 4, 4, 5, 6, 7]>; // expected to be [1, 2, 3, 4, 5, 6, 7]
type Res2 = Unique<[1, "a", 2, "b", 2, "a"]>; // expected to be [1, "a", 2, "b"]
type Res3 = Unique<[string, number, 1, "a", 1, string, 2, "b", 2, number]>; // expected to be [string, number, 1, "a", 2, "b"]
type Res4 = Unique<[unknown, unknown, any, any, never, never]>; // expected to be [unknown, any, never]
Solution
Zur Lösung des Problems benötigen wir ein Hilfsargument in Form eines Akkumulators, um die gefunden, eindeutigen Elemente zwischenzuspeichern.
Zusätzlich definieren wir einen Hilfstyp InArray, der eine Tupel sowie ein Element entgegennimmt und zurückgibt, ob sich das Element bereits in der Tupel befindet
type InArray<L, R extends any[]> = R extends [infer F, ...infer N]
? Equal<L, F> extends true
? true
: InArray<L, N>
: false;
Entsprechend können wir den finalen Typen so erweitern, dass jedes mittels infer extrahierte Element auf die Existenz im Akkumulator geprüft wird. Ist das Element noch nicht im Akkumulator enthalten, so können wir dieses ergänzen.
type Unique<T extends any[], Res extends any[] = []> = T extends [
infer H,
...infer R
]
? InArray<H, Res> extends false
? Unique<R, [...Res, H]>
: Unique<R, Res>
: Res;