Reputation: 9846
I have a generic type defined as follows:
export type LogBuilder<
T extends Logger<U>,
U extends LoggerOptions
> = (options: U) => T;
I can use this as follows:
interface WinstonLogger extends Logger<WinstonOptions> {
// Object.keys(Winston.config.syslog.levels)
emerg: Log;
alert: Log;
crit: Log;
error: Log;
warning: Log;
notice: Log;
info: Log;
debug: Log;
}
const declareWinstonLogger: LogBuilder<WinstonLogger, WinstonOptions> = (options) => {
return ...;
}
Notice that the WinstonLogger
extends with a generic type WinstonOptions
.
Is there a way in LogBuilder
to infer U
from the generic type T<U>
, so that I don't need to specify the second type in LogBuilder<WinstonLogger, WinstonOptions>
?
I know I can define LogBuilder
to have a default value of LoggerOptions
for U
:
export type LogBuilder<
T extends Logger<U>,
U extends LoggerOptions = LoggerOptions
> = (options: U) => T;
and I know Typescript has an infer
keyword, which I attempted unsuccessfully to solve this problem. I'm hoping there's some way to combine these to drop the need to declare the second type generic in LogBuilder
, and have that default to WinstonOptions
, and having the above LogBuilder
definition has it default to LoggerOptions
- is that possible?
Upvotes: 0
Views: 39
Reputation: 23825
The infer
keyword should work here.
export type LogBuilder<
T extends Logger<any>,
> = (options: T extends Logger<infer U> ? U : never) => T;
We can extract the type U
from Logger
in a conditional type for the options
parameter.
Upvotes: 1