String Join

Challenge

Create a type-safe string join utility which can be used like so:

const hyphenJoiner = join("-");
const result = hyphenJoiner("a", "b", "c"); // = 'a-b-c'

Or alternatively:

join("#")("a", "b", "c"); // = 'a#b#c'

When we pass an empty delimiter (i.e ”) to join, we should concat the strings as they are, i.e:

join("")("a", "b", "c"); // = 'abc'

When only one item is passed, we should get back the original item (without any delimiter added):

join("-")("a"); // = 'a'

Solution

Zur Lösung dieses Problems definieren wir einen Hilfstypen, der die Elemente einer Tupel als Zeichenkette zusammenfügt. Dabei wird ein Separator genutzt, der zwei folgende Zeichen trennt.

//Eingabe: ["A", "B"], (Delimiter = "-");
//Ausgabe: `A-B`;
type JoinArrayByDelimiter<T extends string[], D extends string> = T extends [
  infer H,
  ...infer Rest extends string[]
]
  ? Rest["length"] extends 0
    ? H
    : `${string & H}${D}${JoinArrayByDelimiter<Rest, D>}`
  : "";

Wir müssen der Funktionsdeklaration noch die generischen Argumente T hinzufügen. So sollte das Trennzeichen eine Zeichenkette sein und das Argument für den zweiten Aufruf sollte eine Tupel aus Zeichenketten sein.

declare function join<S extends string>(
  delimiter: S
): <T extends string[]>(...parts: T) => JoinArrayByDelimiter<T, S>;

References

Infer types template string