Here is your solution:
const arr = ['a', 'b', 'c'] as const;
type Arr = typeof arr;
type Elem = string
type Mapper<
Arr extends ReadonlyArray<Elem>,
Result extends string = ''
> = Arr extends []
? Result
: Arr extends [infer H]
? H extends Elem
? `${Result},${H}`
: never
: Arr extends readonly [infer H, ...infer Tail]
? Tail extends ReadonlyArray<Elem>
? H extends Elem
? Result extends '' ? Mapper<Tail, `${Result}${H}`> : Mapper<Tail, `${Result},${H}`>
: never
: never
: never;
type Result = Mapper<Arr> // "a,b,c"
function toList<T extends ReadonlyArray<string>>(arr: T) {
return arr.join(',') as Mapper<T>
}
const list = toList(arr);
Playground link
Here you can find more interesting examples
P.S. Please, keep in mind, it is not 100% type safe because I used casting operator as
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…