I am looking for a way to store various functions that each take a single parameter, along with the argument for that parameter.
So far, I have managed to implement type checking for one type of function at a time. However, I am seeking a solution that allows me to pass in multiple types of functions simultaneously and still receive the correct type checking for each function's argument.
type WalkOptions = {
x: number
speed: number
}
type JumpOptions = {
y: number
speed: number
}
type ShootOptions = {
type: string
duration: number
}
const walk = (options: WalkOptions)=>{}
const jump = (options: JumpOptions)=>{}
const shoot = (options: ShootOptions)=>{}
type Action<T extends (options: any) => void> = {
command: T
args: Parameters<T>[0]
}
function add<T extends (options: any) => void>(...actions: Action<T>[]){}
With the code above, I am able to use
add({command: walk, args:{x: 10, speed: 1}})
and obtain accurate type checking on the arguments. Similarly, using add({command: walk, args:{x: 10, speed: 1}}, {command: walk, args:{x: -10, speed: 2}})
works flawlessly.
However, if I try
add({command: walk, args:{x: 10, speed: 1}}, {command: jump, args:{x: 5, speed: 1}})
, I encounter a type error because it expects (options: WalkOptions) => void
instead of (options: JumpOptions) => void
.
Is there a way to utilize add in this manner while still receiving type checking on the arguments specific to each command?
add({
command: walk,
args:{
x: 10,
speed: 1
}
},
{
command: jump,
args:{
y: 5,
speed: 1
}
},
{
command: shoot,
args:{
type: "laser",
duration: 3
}
},
{
command: walk,
args:{
x: -10,
speed: 2
}
})
Additionally, is there a way to create an array of these Actions with type checking, which can then be used with add like add(...actionArray)
?