I am looking for a way to group a set of partially applied functions with only the first parameter(s) being different. Or in other words; The group contains functions accepting any number of parameters of any type but the first application always has to return a function of type (state: State) => Event[]
.
For example a group of functions like this:
const group = {
func1: () => (state: State) => Event[],
func2: (arg: string) => (state: State) => Event[],
func3: (arg: string, arg2: number) => (state: State) => Event[],
}
All of these functions follow the pattern (not updated to accept multiple args):
export type Command = <T>(arg: T) => (state: State) => Partial<Event>[];
However, when I try to type the group like this:
const command: Record<string, Command> = {
func1: () => (state: State) => [{}],
func2: (arg: string) => (state: State) => [{}],
func3: (arg: string, arg2: number) => (state: State) => [{}],
};
Typescript warns me that type T is not assignable to type string.
Type '(arg: string) => (state: State) => {}[]' is not assignable to type 'Command'.
Types of parameters 'arg' and 'arg' are incompatible.
Type 'T' is not assignable to type 'string'
I understand why it is not assignable but I can't figure out how I would then type this grouping of partially applied functions. I basically want to make sure that every function in this grouping follows the pattern of the type Command. That is to say, it should be a partially applied function with any parameters of any type that return a function of the type: (state: State) => Event[]
Is this possible, and if so, how would I do this?
Is it helping to use any
in your type declaration and type the function parameter later in your group like so?
export type Command = (...arg: any[]) => (state: State) => Partial<Event>[];
const command: Record<string, Command> = {
func1: () => (state: State) => [{}],
func2: (arg: string) => (state: State) => [{}],
func3: (arg: string, arg2: number) => (state: State) => [{}],
};
Update
To be more specific with the parameters I would let Typescript infer the function signatures:
export type Command = (state: State) => Partial<Event>[];
const command = {
func1: (): Command => (state: State) => [{}],
func2: (arg: string): Command => (state: State) => [{}],
func3: (arg: string, arg2: number): Command => (state: State) => [{}],
};
command.func1() // OK
command.func1("test") // Err
command.func2() // Err
command.func2("test") // OK
command.func2([]) // Err
command.func3() // Err
command.func3("test", 2) // OK
command.func3([]) // Err
Or explicitly type the group:
export type Command = (state: State) => Partial<Event>[];
interface CommandsGroup {
func1: () => Command;
func2: (arg: string) => Command;
func3: (arg: string, arg2: number) => Command
}
const command: CommandsGroup = {
func1: () => (state: State) => [{}],
func2: (arg: string) => (state: State) => [{}],
func3: (arg: string, arg2: number) => (state: State) => [{}],
};
command.func1() // OK
command.func1("test") // Err
command.func2() // Err
command.func2("test") // OK
command.func2([]) // Err
command.func3() // Err
command.func3("test", 2) // OK
command.func3([]) // Err