Encountering a TypeScript error with our custom event bus:
TS2345: Argument of type 'unknown' is not assignable to parameter of type 'AccountInfo | undefined'.
Type 'unknown
The event bus utilizes unknown[]
as an argument for callback functions. Since it's impractical to set every possible type within the arguments of the event bus, we are unsure how to accurately infer the type in TypeScript or if there's an alternative solution?
// eventBus.ts
type TCallBack = (...args: unknown[]) => boolean | void
const subscriptions: { [key: string]: TCallBack[] } = {}
interface ISubscription {
eventName: string
callback: TCallBack
}
export function unsubscribe({ eventName, callback }: ISubscription) {
if (!subscriptions[eventName]) { return }
const index = subscriptions[eventName].findIndex((l) => l === callback)
if (index < 0) { return }
subscriptions[eventName].splice(index, 1)
}
export function subscribe({ eventName, callback }: ISubscription) {
if (!subscriptions[eventName]) { subscriptions[eventName] = [] }
subscriptions[eventName].push(callback)
return () => unsubscribe({ eventName, callback })
}
export function publish(eventName: string, ...args: unknown[]) {
if (!subscriptions[eventName]) { return }
for (const callback of subscriptions[eventName]) {
const result = callback(...args)
if (result === false) { break }
}
}
In our application, we trigger the login
event to notify all subscribers:
// authServce.ts
publish('login', account)
Subsequently, a subscriber is activated:
// authStore.ts
export const setAccount = (account?: AuthenticationResult['account']) => {
if (account) state.account = account
else state.account = defaultState().account
console.log('setAccount: ', state.account)
}
subscribe({
eventName: 'login',
callback: (account) => {
setAccount(account)
},
})
The code functions smoothly, but resolving the TS error would be beneficial.