I'm trying to write a function that takes as arguments two keys of a specific object inside an array. The keys are the following:
- A string used to index a specific object
- A function (from which I need the types of its parameters)
The array of objects is the following
const obj = [
{
name: "number",
func: (foo: number) => foo,
},
{
name: "string",
func: (foo: string) => foo,
},
{
name: "array",
func: (foo: string[]) => foo,
},
];
And this is my approach
type SingleObject = typeof obj[number];
type Name<T extends SingleObject> = T["name"];
type FuncParams<T extends SingleObject> = Parameters<T["func"]>;
const myFunc = async <T extends SingleObject>(
name: Name<T>,
params: FuncParams<T>
) => {
// Do something
};
I thought that when calling myFunc passing "array" (for example) as the first parameter, it would identify the object in question and correctly assign the parameters of the other key (which in this case should be Parameters<(foo: string[] => foo)>)
This is clearly not the case, as I can do the following without any problems
myFunc("number", ["fo"]); // Should only allow a number as the second parameter
myFunc("string", [34]); // Should only allow a string as the second parameter
myFunc("array", [34]); // Should only allow an array of strings as the second parameter
Reference
Parameters<T["func"]>results in a type ofnumber | string | string[]forparamsin this case, since allT["func"]does is aggregate all the types of the given array. Thats why it works. Now how to get it to work how you would like it to is an interesting problem.