I have a function that accepts a record of Handler<I, O>
and returns a function that returns the O
of one of the handlers:
type Handler<I, O> = { i: I, o: O, handler: (i: I) => O };
function handlerGroup<I, O>(handlers: Record<string, Handler<I, O>>): (key: string) => O {
return (key: string) => {
const { i, handler } = handlers[key];
return handler(i);
}
}
For example:
const handleT1: Handler<number, number> = { i: 1, o: 1, handler: (i) => i }
const handleT2: Handler<number, string> = { i: 1, o: "1", handler: (i) => i.toString() }
handlerGroup({ T1: handleT1 }) //: (key: string) => number
handlerGroup({ T2: handleT2 }) //: (key: string) => string
But the problem starts when I try to add more than 1 record:
// Type 'Handler<number, string>' is not assignable to type 'Handler<number, number>'.
// Types of property 'o' are incompatible.
// Type 'string' is not assignable to type 'number'.(2322)
handlerGroup({ T1: handleT1, T2: handleT2 }) // expected: (key: string) => number | string
The problem is due to how I typed handleGroup
, which I'm not entirely sure how to approach it.
So my question is, how can I let handleGroup
infer all of the possible O
based on the record?
I solved it by moving the handler itself as a generic, and then infer its O:
type Handler<I, O> = { i: I, o: O, handler: (i: I) => O };
type A<T> = T extends Record<string, Handler<any, infer U>> ? U : never;
function handlerGroup<H extends Record<string, Handler<any, any>>>(handlers: H): (key: string) => A<typeof handlers> {
return (key: string) => {
const { i, handler } = handlers[key];
return handler(i);
}
}
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.