How can this be implemented with types?
const createConstants = (...keys) => {
let record = {};
keys.forEach(key => {
record[key] = key;
});
return record;
};
If you don't mind a little bit of assertion inside the function, you can do this:
const createConstants = <K extends string>(...keys: K[]): {[Key in K]: Key} => {
let record = {} as {[Key in K]: Key};
keys.forEach(key => {
record[key] = key;
});
return record;
};
createConstants("a", "b", "c"); // { a: "a"; b: "b"; c: "c";}
A Record type is presumably not actually useful here since something like Record<Keys, Keys> is broader than the return type of the function. You can't match keys to values with a Record type.
After some further consideration, a more typesafe version of this would require that the input is of a tuple type. This will prevent false types being returned from inputs like ("a" | "b")[], which cannot be guaranteed to have either property present:
const createConstants = <K extends string>(...keys: [K, ...K[]): {[Key in K]: Key}
createConstants("a", "b", "c"); // ok
const tuple = ["a", "b", "c"] as const;
createConstants(...tuple) // ok
const undetermined = [] as ("a" | "b")[];
createConstants(...undetermined) // not ok
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With