Is it possible to make Typescript figure out the types of the arguments of this callback based on an interface?
export interface MiddlewareEvent {
onNewAccount: (accountId: string, timestamp: number) => void,
onAccountDelete: (accountId:string, timestamp:number)=>void,
}
const middlewareMap: Map<keyof MiddlewareEvent,((...arg: any) => void )[]> = new Map();
function registerMiddleWare(
eventId: keyof MiddlewareEvent,
middleware: ((...arg: any) => void)
) {
const existing = middlewareMap.get(eventId);
if (!existing?.length) {
middlewareMap.set(eventId, [middleware]);
} else {
existing.push(middleware);
}
}
registerMiddleWare(`onNewAccount`, (accountId: number, datetime: string) => {
console.log(`Wait, Typescript should have prevented this`)
console.log(`account Id is string not number`)
console.log(`datetime has been changed to timestamp and is now a number`)
})
The idea is to just pass the property of the interface as a string (or enum? ) to a function as first parameter and Typescript should figure out of the types of the argument of the callback which is the second parameter by looking that key in the interface.
This won`t require the user to manually pass a generic type argument everytime.
Sure, you just need an inferred generic function. Let it infer the eventId
being passed in, and then drill into MiddlewareEvent
based on that key.
function registerMiddleWare<EventName extends keyof MiddlewareEvent>(
eventId: EventName,
middleware: MiddlewareEvent[EventName]
) { /* ... */ }
registerMiddleWare(`onNewAccount`, (accountId: number, datetime: string) => {})
// Argument of type
// '(accountId: number, datetime: string) => void'
// is not assignable to parameter of type
// '(accountId: string, timestamp: number) => void'
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.