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 . 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{Separator}${T[0]}
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 OverflowIf your definition of "empty" means falsy values (e.g., nulls, undefineds, empty strings, 0, etc), consider:
var address = "foo";
var city;
var state = "bar";
var zip;
text = [address, city, state, zip].filter(Boolean).join(", ");
console.log(text)
.filter(Boolean) is the same as .filter(x => Boolean(x)).
If your definition of "empty" is different, then you'll have to provide it, for example:
[...].filter(x => typeof x === 'string' && x.length > 0)
will only keep non-empty strings in the list.
(obsolete jquery answer)
var address = "foo";
var city;
var state = "bar";
var zip;
text = $.grep([address, city, state, zip], Boolean).join(", "); // foo, bar
Yet another one-line solution, which doesn't require jQuery:
var address = "foo";
var city;
var state = "bar";
var zip;
text = [address, city, state, zip].filter(function(val) {
return val;
}).join(', ');
console.log(text);
Simply
return str1 + ", " + str2;
If the strings are in an Array, you can use Array.prototype.join method, like this
var strings = ["a", "b", "c"];
console.log(strings.join(", "));
Output
a, b, c
try this:
function test(str1, str2) {
var res = str2 + ',' + str1;
return res;
}