#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 будут жаловаться) — если их нет, он становится пустым массивом, а не неопределенным.