I'm trying to make a list ( example below ) and map it to the parameters of a function. I imagine the arguments being an object with keys that match the names of the params, and the values being the options for each arg (whether it's required or more important, what type ).
interface Command<T> { // Theese are the parts that I'm curious about,
args: T, // idk if its even possible, or if there's another solution.
run(...args: T) { //
}
}
const Arguments = {
name: {
type: "string",
required: true,
},
duration: {
type: "number",
required: false,
}
};
const cmd: Command<typeof Arguments> = {
args: Arguments,
run(name, duration) {
console.log(`banned ${name} for ${duration ?? "forever"}`);
}
}
If it is possible or you have any ideas of how to achieve this, please let me know as I've been struggling with this for days now 😔.
You'll need a little more magic to do this. First a type that describes the type of the arguments object:
type ArgsObject = Record<string, { type: "string" | "number" | "boolean"; required: boolean }>;
Then we'll map strings to their actual types (i.e. "string" to string
):
type MapToType = {
string: string;
number: number;
boolean: boolean;
// more if needed
};
And finally we map over the arguments and get the type for each:
type ArgsToContext<Args extends ArgsObject> = {
[K in keyof Args]: MapToType[Args[K]["type"]] | IsOptional<Args[K]>;
};
Where IsOptional
is defined as:
type IsOptional<T extends ArgsObject[string]> = T["required"] extends true ? never : undefined;
This is because if it is required, it gives us never
, and Type | never
is always Type
. However if it is not required (optional), it gives us undefined
, resulting in the desired Type | undefined
Here is a playground showcasing this.