Машинопись: введите группу частично применяемых функций с переменным числом и типом параметров, которые все возвращают функцию одного типа.

Я ищу способ сгруппировать набор частично применяемых функций, при этом будет отличаться только первый параметр (ы). Или другими словами; Группа содержит функции, принимающие любое количество параметров любого типа, но первое приложение всегда должно возвращать функцию типа (state: State) => Event[].

Например, группа таких функций:

const group = { 
  func1: () => (state: State) => Event[],
  func2: (arg: string) => (state: State) => Event[],
  func3: (arg: string, arg2: number) => (state: State) => Event[],
}

Все эти функции следуют шаблону (не обновлены для приема нескольких аргументов):

export type Command = <T>(arg: T) => (state: State) => Partial<Event>[];

Однако, когда я пытаюсь ввести группу так:

const command: Record<string, Command> = {
  func1: () => (state: State) => [{}],
  func2: (arg: string) => (state: State) => [{}],
  func3: (arg: string, arg2: number) => (state: State) => [{}],
};

Typescript предупреждает меня, что тип T не может быть назначен строке типа.

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'

Я понимаю, почему это не может быть назначено, но я не могу понять, как бы я тогда набрал эту группу частично применяемых функций. Я в основном хочу убедиться, что каждая функция в этой группировке следует шаблону типа Command. То есть это должна быть частично применяемая функция с любыми параметрами любого типа, которые возвращают функцию типа: (state: State) => Event[]

Возможно ли это, и если да, то как мне это сделать?


person Terry van Walen    schedule 01.06.2021    source источник


Ответы (1)


Помогает ли использование any в объявлении вашего типа и ввод параметра функции позже в вашей группе, например?

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) => [{}],
};

Обновить

Чтобы быть более конкретным с параметрами, я бы позволил Typescript вывести сигнатуры функций:

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

Или явно введите группу:

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
person Mue    schedule 01.06.2021
comment
Интересно и спасибо за ответ. Когда я пробую это сделать, все входные аргументы функции будут правильными в соответствии с машинописным текстом. Другими словами, машинописный текст не предупредит / не поймает меня, если я укажу неправильный тип во время разработки. Тип command.func1 () всегда будет: (...arg: any[]): (state: State) => Event[] Итак, для func1, который ожидает строку, typescript не поймает меня, если я это сделаю: command.func1(["val"]); - person Terry van Walen; 01.06.2021
comment
Ты прав! Это не очень полезно при рассмотрении типов параметров. Я немного обновил свой ответ. - person Mue; 02.06.2021
comment
Спасибо, Му, это не совсем то, что я хочу, но то, что я хочу, вероятно, невозможно, и это действительно лучший подход. - person Terry van Walen; 03.06.2021