With our home made event bus we receive the following TS error:
TS2345: Argument of type 'unknown' is not assignable to parameter of type 'AccountInfo | undefined'.
Type 'unknown
The event bus uses type unknown[]
as an argument for a callback function. It's of course not possible to set every possible type within the arguments of the event bus. So we're a bit stuck here on how to have TypeScript infer the type correctly of the argument or if there is another 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 }
}
}
At some point in the app we publish the login
event to trigger all subscribers:
// authServce.ts
publish('login', account)
After which a subscriber is triggered:
// 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)
},
})
This code works flawless but it would be nice to be able to solve the TS error.
Extend
any
and set the default toany
(so you don't need to every time specify the type)