Turning a generic string array into a union of string literals

Viewed 205

I found that when I use a generic variadic, I can successfully coerce a function's input of strings into a Union of the literal values passed

declare function variadicGenericArray<Items extends string[]>(...items: Items): {[value in Items[number]: value}
const test = variadicGenericArray("One", "Two");
type testType = typeof Test; // {"One": "One", "Two": "Two"}

However when I try to extract these types using a normal array as the argument, then I don't get a union of literals.

declare function nonVariadicGenericArray<Items extends string[]>(items: Items): {[value in Items[number]: value}
const test = nonVariadicGenericArray(["One", "Two"]);
type testType = typeof Test; // {[x: string]: string}

What can I do to ensure that testType has the type {"One": "One", "Two": "Two"} and still have the function take in an array rather than variadic arguments?

An important note. I'm trying to write a function definition here, and the function is supposed to be generic, so I can't just declare type Values = "One" | "Two" or type Values = ["One", "Two"] as const and use those, since then the function would no longer be generic

1 Answers

Played around a little and it looks like I can do this

declare function nonVariadicGenericArray<Items extends readonly string[]>(items: Items): {[value in Items[number]: value}
const test = nonVariadicGenericArray(["One", "Two"] as const);
type testType = typeof Test; // {"One": "One", "Two": "Two"}

Now I'll need to figure out which API is the better developer UX, but at least I have an answer now.

Related