I'd like to be able to convert an array of strings into a dictionary where they strings passed in become the keys of the object (and the value is set to true):
// obj = { foo: true, bar: true );
const obj = toObject("foo", "bar");
This is super simple at runtime with JS but I want the types preserved in TS and this is surprising challenging. Here's an implementation that works at runtime but ends up dumping the object out with a type of all. Yuck.
function toObject<T extends readonly string[]>(...keys: T) {
return keys.reduce((acc, k) => {
acc[k] = true;
return acc;
}, {} as any);
}
With all we're left with zero value but it's still almost better than not stating as any in the reducer. At least we can index the dictionary at run time. Had we left it alone the type would have been an empty object. Instead what I need is some way to convert an array of strings to union of the strings. Once I have that I can simply type the initial state of the reducer to:
{} as Record<UnionOfStrings, true>;
That said, I can't figure out how to do this conversion.
Anyone know how?
const arr = ["foo", "bar"] as const; type Union = typeof arr[number];