Как правильно использовать любые и / или неизвестные для аргументов функции

#javascript #typescript

#javascript #typescript

Вопрос:

Мы пытаемся преобразовать шину событий из JavaScript в TypeScript. Что нас беспокоит, так это этот фрагмент кода:

 export function publish(eventName, ...args) {
  if (!subscriptions[eventName]) { return }

  for (const callback of subscriptions[eventName]) {
     const result = callback(...args)

     if (result === false) { break }
  }
}
  

Переведено на TypeScript:

 // eslint-disable-next-line @typescript-eslint/no-explicit-any
type TCallBack = (...args: any) => void

const subscriptions: { [key: string]: TCallBack[] } = {}

export function publish(eventName: string, ...args: unknown[]) {
  if (!subscriptions[eventName]) { return }

  for (const callback of subscriptions[eventName]) {
    callback(...args)
  }
}
  

Ошибок нет, но я не совсем уверен, что мы правильно использовали тип any и unknown для аргументов callback . У callback может быть один, несколько аргументов или вообще не быть аргументов, и аргумент может быть любого типа. Является ли это правильным способом использования any и unknown>

Комментарии:

1. вы должны добавить «необязательный» оператор в …args: …args?: unknown[]

2. Я бы ожидал, что тип распространения, подобный ...args , будет минимально типом массива, так что, возможно any[] . Также не должен обратный вызов возвращать логическое значение? Вы сравниваете возвращаемое значение с false в первом примере, мне непонятно, почему для перевода на typescript потребовалось изменение фактического поведения .

3. Потому что, если я сохраню if (result === false) , я получу эту ошибку TS «Это условие всегда будет возвращать ‘false’, поскольку типы ‘void’ и ‘boolean’ не имеют перекрытия».

4. Я думаю, @jonrsharpe имел в виду, что вы должны добавить boolean в качестве допустимого возвращаемого типа TCallBack : type TCallBack = (...args?: unknown[]) => boolean | void

5. @SandroSchaurer не имеет смысла, чтобы аргумент rest был необязательным (и я думаю, TS будут жаловаться) — если их нет, он становится пустым массивом, а не неопределенным.