Below is a potential solution that can trigger some wonders
:
declare function magic<T extends string[]>(
...propertyNames: T
): Record<T[number], any>;
const result = magic("alpha", "bravo");
type ResultType = typeof result; // {alpha: any; bravo: any;}
Putting the ResultType
to test:
const t1: ResultType = {
alpha: "foo",
bravo: 42,
wannaBe: 3 // error (OK)
};
You have the option to further limit the usage of the any
type in Record<T[number] any>
by adding an extra type parameter, since any
doesn't provide much useful typing.
declare function magic<T extends string[], R>(
...propertyNames: T
): Record<T[number], R>;
A Little Elaboration
T[number]
grants us access to all item values as a union type. For example,
type T = ["alpha", "bravo"]
type TItems = T[number] // "alpha" | "bravo"
Record
ensures that we have all item values "alpha" | "bravo"
as property keys.
- The tuple type can be deduced with the assistance of generic rest parameters.
Playground