You can get close, but there's a problem: unions don't really have an order you can rely on. The compiler is fully within its rights to rearrange if it wants to. There's also some other weird cases with unions as well. I recommend looking at this answer by Jcalz about how to turn a union into a tuple for more details and pitfalls: https://stackoverflow.com/a/55128956/3794812

If we can change your requirements so the starting point is a tuple (eg, ['foo', 'bar', 'baz']) we'll be able to do it with no problem. But if you must start with a union, then we have to do a hacky and unreliable conversion from union to tuple. Which you shouldn't do. Seriously, see Jcalz's answer for all the reasons why you shouldn't do it.


Step 1: Utility to split a tuple into its Head and Tail

The plan is to take the tuple of strings and recursively join them together. To do that, i need to be able to break off the head ("foo", for the first step) and the tail (["bar", "baz"]). The head is easy, that's just T[0], where T is the tuple. For the tail, we have this utility type:

type Tail<T extends string[]> = T extends [string, ...infer TailType] ? TailType : never;

Step 2: Recursively do the joining

The following type takes in a string (H for "head"), an array of strings (T for "tail"), and a string for the separator. If the array has exactly one string in it, then the result is just to join them together with the separator, as in {Separator}${T[0]}. If there's more than one string, we need to recursively repeat the process, joining the head with whatever we get by joining the tail together

type JoinRecursive<H extends string, T extends string[], Separator extends string> = 
  Tail<T> extends [string, ...string[]] 
    ? `{Separator}${JoinRecursive<T[0], Tail<T>>}` 
    : `{Separator}${T[0]}`

Step 3: Provide an entry point

The recursive generic expects it to already be split into a head and a tail, so for convenience, i'll make a Join type that can take in the string tuple directly, and then will do that first split:

type Join<T extends string[], Separator extends string> = 
  Tail<T> extends string[] 
    ? JoinRecursive<T[0], Tail<T>, Separator> 
    : T[0];

Putting it together:

And here's how it then gets used:

type UnionTuple = ['foo', 'bar', 'baz'];
// If you must start from a union, the best that can be done is
//   Jcalz's TuplifyUnion hack. But don't do this.
// type UnionStr = 'foo' | 'bar' | 'baz';
// type UnionTuple = TuplifyUnion<UnionStr>;

type Test = Join<UnionTuple, ','> // 'foo,bar,baz'
type Test2 = Join<UnionTuple, '*'> // 'foo*bar*baz'

Playground link

Answer from Nicholas Tower on Stack Overflow
๐ŸŒ
TutorialsPoint
tutorialspoint.com โ€บ typescript โ€บ typescript_array_join.htm
TypeScript - Array join()
join() method joins all the elements of an array into a string. separator โˆ’ Specifies a string to separate each element of the array. If omitted, the array elements are separated with a comma.
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ typescript-array-join-method
TypeScript Array join() Method - GeeksforGeeks
July 12, 2024 - Here, we will see the syntax of the join() method and understand its parameters. ... separator (Optional): A string used to separate each element of the array in the resulting string. If omitted, the array elements are separated by commas.
๐ŸŒ
Educative
educative.io โ€บ answers โ€บ what-is-the-join-method-of-an-array-in-typescript
What is the join() method of an array in TypeScript?
The join() method in TypeScript is used to join the elements of an array as a string. ... separator: This is a character or string that separates each element of the array when joined as a string.
๐ŸŒ
Bobby Hadz
bobbyhadz.com โ€บ blog โ€บ javascript-concatenate-strings-with-separator
Concatenate Strings with a Separator using JavaScript | bobbyhadz
March 3, 2024 - To concatenate strings with a separator, add the strings to an array and call the `join()` method on the array, passing it the separator as a parameter.
๐ŸŒ
SPGuides
spguides.com โ€บ typescript-array-to-string-with-separator
How to Convert Typescript Array to String With Separator? โ€“ Learn SharePoint, Microsoft Power Platform and SPFx Tutorials โ€“ SPGuides
July 21, 2025 - The join method in TypeScript is ... returns a new array with the same items as the original array. By using the join method on the new array, to convert it to a string with the separator between each item....
Top answer
1 of 1
1

You can get close, but there's a problem: unions don't really have an order you can rely on. The compiler is fully within its rights to rearrange if it wants to. There's also some other weird cases with unions as well. I recommend looking at this answer by Jcalz about how to turn a union into a tuple for more details and pitfalls: https://stackoverflow.com/a/55128956/3794812

If we can change your requirements so the starting point is a tuple (eg, ['foo', 'bar', 'baz']) we'll be able to do it with no problem. But if you must start with a union, then we have to do a hacky and unreliable conversion from union to tuple. Which you shouldn't do. Seriously, see Jcalz's answer for all the reasons why you shouldn't do it.


Step 1: Utility to split a tuple into its Head and Tail

The plan is to take the tuple of strings and recursively join them together. To do that, i need to be able to break off the head ("foo", for the first step) and the tail (["bar", "baz"]). The head is easy, that's just T[0], where T is the tuple. For the tail, we have this utility type:

type Tail<T extends string[]> = T extends [string, ...infer TailType] ? TailType : never;

Step 2: Recursively do the joining

The following type takes in a string (H for "head"), an array of strings (T for "tail"), and a string for the separator. If the array has exactly one string in it, then the result is just to join them together with the separator, as in {Separator}${T[0]}. If there's more than one string, we need to recursively repeat the process, joining the head with whatever we get by joining the tail together

type JoinRecursive<H extends string, T extends string[], Separator extends string> = 
  Tail<T> extends [string, ...string[]] 
    ? `{Separator}${JoinRecursive<T[0], Tail<T>>}` 
    : `{Separator}${T[0]}`

Step 3: Provide an entry point

The recursive generic expects it to already be split into a head and a tail, so for convenience, i'll make a Join type that can take in the string tuple directly, and then will do that first split:

type Join<T extends string[], Separator extends string> = 
  Tail<T> extends string[] 
    ? JoinRecursive<T[0], Tail<T>, Separator> 
    : T[0];

Putting it together:

And here's how it then gets used:

type UnionTuple = ['foo', 'bar', 'baz'];
// If you must start from a union, the best that can be done is
//   Jcalz's TuplifyUnion hack. But don't do this.
// type UnionStr = 'foo' | 'bar' | 'baz';
// type UnionTuple = TuplifyUnion<UnionStr>;

type Test = Join<UnionTuple, ','> // 'foo,bar,baz'
type Test2 = Join<UnionTuple, '*'> // 'foo*bar*baz'

Playground link

๐ŸŒ
Webdevtutor
webdevtutor.net โ€บ blog โ€บ typescript-strings-join
Mastering TypeScript Strings: A Guide to join()
You can customize the separator by passing it as an argument to the join() method. For example: const numbers = [1, 2, 3, 4]; const result = numbers.join(' - '); // Output: "1 - 2 - 3 - 4" The join() method is not limited to arrays of strings. You can also use it with arrays of objects, by ...
๐ŸŒ
Webdevtutor
webdevtutor.net โ€บ blog โ€บ typescript-string-join
Mastering TypeScript String Join: A Comprehensive Guide
Custom String Join: This method allows you to specify a custom separator or delimiter to separate the concatenated strings. Let's start with some examples of simple string join: const arr = ['Hello', 'world!', 'This', 'is']; console.log(arr.join()); // Output: "Hello world!
Find elsewhere
๐ŸŒ
Webdevtutor
webdevtutor.net โ€บ blog โ€บ typescript-string-concat-with-separator
How to Concatenate Strings in TypeScript with a Separator
- TypeScript!" In this example, we define a function concatenateStringsUsingSpreadOperator that takes a separator as an argument. We then create an array of strings and use the join method to concatenate them with the separator.
๐ŸŒ
Webdevtutor
webdevtutor.net โ€บ blog โ€บ typescript-join-with-comma
How to Join Strings with Comma in TypeScript
function joinWithComma(strings: string[]): string { return strings.reduce((prev, current) => `${prev}, ${current}`); } const fruits: string[] = ["apple", "banana", "orange"]; const result: string = joinWithComma(fruits); console.log(result); // Output: "apple, banana, orange" Template literals in TypeScript provide a convenient way to interpolate values within strings.
๐ŸŒ
SamanthaMing
samanthaming.com โ€บ tidbits โ€บ 15-4-ways-to-combine-strings
4 Ways to Combine Strings in JavaScript | SamanthaMing.com
Here are 4 ways to combine strings in JavaScript. My favorite way is using Template Strings. Why? Because itโ€™s more readable, no backslash to escape quotes, no awkward empty space separator, and no more messy plus operators ๐Ÿ‘ ยท const icon = '๐Ÿ‘‹'; // Template Strings `hi ${icon}`; // join() Method ['hi', icon].join(' '); // Concat() Method ''.concat('hi ', icon); // + Operator 'hi ' + icon; // RESULT // hi ๐Ÿ‘‹
๐ŸŒ
DEV Community
dev.to โ€บ ncpa0cpl โ€บ typescript-concatenate-multiple-string-literals-c59
TypeScript string literal type concatenation - DEV Community
July 1, 2022 - In the TypeScript version 4.7 and upwards the Concat utility type can be simplified like so: export type Concat<T extends string[]> = T extends [ infer F extends string, ...infer R extends string[] ] ? `${F}${Concat<R>}` : ''; And here's a join function and Concat utility type with a separator:
๐ŸŒ
MDN Web Docs
developer.mozilla.org โ€บ en-US โ€บ docs โ€บ Web โ€บ JavaScript โ€บ Reference โ€บ Global_Objects โ€บ Array โ€บ join
Array.prototype.join() - JavaScript - MDN Web Docs
4 days ago - The join() method of Array instances returns a new string that is the concatenation of all elements in this array, separated by commas or a specified separator string. If the array has only one item, that item's stringification is returned without using the separator.
๐ŸŒ
xjavascript
xjavascript.com โ€บ blog โ€บ typescript-join-array-of-strings
Mastering String Array Joining in TypeScript โ€” xjavascript.com
For example: const stringArray: ... concatenate all the elements of an array into a single string. The join method takes an optional separator as an argument....
๐ŸŒ
daily.dev
daily.dev โ€บ home โ€บ blog โ€บ webdev โ€บ join method javascript: faqs answered
Join Method JavaScript: FAQs Answered | daily.dev
May 25, 2026 - The join() method is super useful for anyone coding in JavaScript. It helps you change a list of things into a single line of text. Here's what to remember: join() makes a string from an array by putting a separator, like a comma, between each part.
๐ŸŒ
MDN Web Docs
developer.mozilla.org โ€บ en-US โ€บ docs โ€บ Web โ€บ JavaScript โ€บ Reference โ€บ Global_Objects โ€บ TypedArray โ€บ join
TypedArray.prototype.join() - JavaScript - MDN Web Docs
The join() method of TypedArray instances returns a new string that is the concatenation of all elements in this typed array, separated by commas or a specified separator string. If the typed array has only one item, that item's stringification is returned without using the separator.