Winston 自定义日志级别打字稿定义

leo*_*mes 6 winston typescript

我正在开发一个节点应用程序并使用 Typescript。我有winston 3。在我的代码中我添加了自定义日志级别;

const myCustomLevels = {
    levels: {
        data: 10,
        protocol: 9,
        debug: 8,
        info: 7,
        notice: 6,
        note: 5,
        warn: 4,
        error: 3,
        crit: 2,
        alert: 1,
        emerg: 0,
    }
}
Run Code Online (Sandbox Code Playgroud)

然后

const logger = winston.createLogger({
    level: data,
    levels: myCustomLevels.levels,
    format: winston.format.combine(
        winston.format.json()
    ),
    transports: [new winston.transports.Console()],
});
Run Code Online (Sandbox Code Playgroud)

我需要帮助解决的问题是当我使用 Typescript 记录器时发出的抱怨。

logger.protocol({});
Run Code Online (Sandbox Code Playgroud)

在本例中,类型为const logger: winston.Logger,并且 ts 表示[ts] Property 'protocol' does not exist on type 'Logger'. [2339]。Typescript 不知道我的水平。

我该如何纠正这个问题,以便tsc了解我在记录器上的级别?

Tit*_*mir 14

不幸的是,当前编写的定义不允许自定义日志级别。最简单的解决方案是将返回的记录器转换为记录器和包含额外方法的类型的交集。Record我们可以使用映射类型根据您的 const 声明创建此类型keyof

import * as winston from 'winston'
const logger = winston.createLogger({
    level: data,
    levels: myCustomLevels.levels,
    format: winston.format.combine(
        winston.format.json()
    ),
    transports: [new winston.transports.Console()],
}) as winston.Logger & Record<keyof typeof myCustomLevels['levels'], winston.LeveledLogMethod>;

logger.protocol({})
Run Code Online (Sandbox Code Playgroud)

请注意,我尝试过增强现有的模块定义,但因为createLogger被声明为具有内联函数签名的变量,所以我们无法真正通过增强来扩展它。

如果这对您来说是一个普遍问题,您可以编写一个保留级别的通用函数:

function createWinstonLogger<T>(options?: Pick<winston.LoggerOptions, Exclude<keyof winston.LoggerOptions, 'levels'>> & { levels: T }) {
    return winston.createLogger(options) as winston.Logger & Record<keyof T, winston.LeveledLogMethod>
}
const logger = createWinstonLogger({
    level: data,
    levels: myCustomLevels.levels,
    format: winston.format.combine(
        winston.format.json()
    ),
    transports: [new winston.transports.Console()],
});
logger.protocol({})
Run Code Online (Sandbox Code Playgroud)