I have an array like:
const arr = ['a', 'b'] as const;
// type: readonly ["a", "b"]
Now I want to join the strings in the array:
const joined = arr.join('');
// type: string
My goal is to write a function that joins strings in an array and returns them as a literal string type ("ab"
).
Does someone know if this is even possible? I think it should be, since all the type information needed is given. I don't expect a full solution to the problem - maybe just a hint for further research would be great.
Here is a version that works with both readonly and mutable tuples types and a separator.
type Join<
TElements,
TSeparator extends string,
> = TElements extends Readonly<[infer First, ...infer Rest]>
? Rest extends ReadonlyArray<string>
? First extends string
? `${First}${Rest extends [] ? '' : TSeparator}${Join<Rest, TSeparator>}`
: never
: never
: '';
type MutableTuple = ["a", "b", "c"];
type MutableTupleJoined = Join<MutableTuple, " | ">;
// ^? "a | b | c"
type ReadonlyTuple = readonly ["a", "b", "c"];
type ReadonlyTupleJoined = Join<ReadonlyTuple, " | ">;
// ^? "a | b | c"
A readonly type often comes from const
assertions e.g.
const tuple = ["a", "b", "c"] as const;
type Joined = Join<typeof tuple, " | ">;
When inlining the tuple type, it is usually mutable e.g.
type Joined = Join<["a", "b", "c"], " | ">;