18

I can't figure how to use the logging module Winston in typescript. I have an error when I try to set the logger level, and another one when I try to log an error:

import * as logger from "winston";

logger.level = 'debug';
// [ts] Cannot assign to 'level' because it is a constant or a read-only property.

logger.error(new Error('test'));
// [ts] Argument of type 'Error' is not assignable to parameter of type 'string'.

I have added both winston and @types/winston to my project.


Edit: to complete Joshua answer, it seem that by default winston logs to... nowhere. You have to add a transport to make it work:

import * as logger from "winston";

logger.configure({
    level: 'debug',
    transports: [
        new logger.transports.Console({
            colorize: true
        })
    ]
});
Christophe Le Besnerais
  • 3,895
  • 3
  • 24
  • 44

1 Answers1

8

Here are the type definitions for Winston:

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/winston/index.d.ts

If you look at the bottom of the file, the default export is declared as const, so when you try to modify the level property, it complains at you because you are trying to modify a const object. Here are the relevant lines:

declare const winston: winston.Winston;
export = winston;

Instead of trying to set that property directly, try using the configure method (note that your logger import is of type Winston:

logger.configure({
    level: 'verbose',
    ...
})

If this doesn't work (I'm not sure exactly what else the configure call expects), you might try creating a new LoggerInstance, which you will be able to modify.

Your second error is because you're passing an Error object where a string is expected. The declaration of Winston.info is here:

info: LeveledLogMethod;

And here is the LeveledLogMethod interface:

interface LeveledLogMethod {
    (msg: string, callback: LogCallback): LoggerInstance;
    (msg: string, meta: any, callback: LogCallback): LoggerInstance;
    (msg: string, ...meta: any[]): LoggerInstance;
}
Joshua Breeden
  • 1,844
  • 1
  • 16
  • 29
  • does this mean it is impossible to log error with Winston ? that sound insane to me. – Christophe Le Besnerais Jul 19 '17 at 09:35
  • You could log the `Error`'s `message` property. – Joshua Breeden Jul 19 '17 at 13:50
  • this actually log the error: let err:any = new Error('test'); logger.error(err); I thing there is a problem with the type definition for winston. – Christophe Le Besnerais Jul 19 '17 at 15:25
  • 1
    Another way that should work would be to use the third form defined in the interface, which is to do something like `logger.error("test", new Error("test error");` I think you are correct that the type definition is incorrect. I think it should also include `(...meta: any[]): LoggerInstance;`, but I'm not sure about the syntax exactly. After looking through the source, it appears to me that the `log` method tries to smartly handle objects it receives such as `Error`s, and the `meta` parameter is an indication of that. – Joshua Breeden Jul 19 '17 at 17:31
  • I have opened an issue : https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18220 – Christophe Le Besnerais Jul 21 '17 at 07:20