如何让LogBuilder从T的泛型参数中自动推导U类型?
问题:自动推导LogBuilder的泛型参数U
现有泛型类型定义:
export type LogBuilder< T extends Logger<U>, U extends LoggerOptions > = (options: U) => T;
使用示例:
interface WinstonLogger extends Logger<WinstonOptions> { emerg: Log; alert: Log; crit: Log; error: Log; warning: Log; notice: Log; info: Log; debug: Log; } const declareWinstonLogger: LogBuilder<WinstonLogger, WinstonOptions> = (options) => { return ...; }
需求:WinstonLogger继承自Logger<WinstonOptions>,希望LogBuilder能从T的继承关系中自动推导U的类型,无需手动指定第二个泛型参数,同时能结合默认值实现当推导不出时使用LoggerOptions。
解决方案:结合infer与默认值实现自动推导
可以通过infer关键字从T的约束中提取对应的U类型,同时给U设置默认值,修改后的LogBuilder定义如下:
export type LogBuilder< T extends Logger<any>, U extends LoggerOptions = T extends Logger<infer UInfer> ? UInfer : LoggerOptions > = (options: U) => T;
核心逻辑说明:
- 将
T的约束调整为Logger<any>,避免原定义中T和U的循环依赖问题; - 利用条件类型+
infer:从T继承的Logger中自动提取泛型参数UInfer,如果无法提取(比如T未明确继承带泛型的Logger),则回退到默认的LoggerOptions; - 最终使用时,只需传入
T类型,U会自动推导,无需手动声明。
优化后的使用示例:
// 无需指定第二个泛型参数,U会自动推导为WinstonOptions const declareWinstonLogger: LogBuilder<WinstonLogger> = (options) => { // options的类型自动识别为WinstonOptions return ...; };
内容的提问来源于stack exchange,提问作者Nick Bull
相关产品推荐
相关产品推荐

