Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

custom level not work in typescript #1523

Open
1 of 2 tasks
cheerfyt opened this issue Nov 2, 2018 · 9 comments
Open
1 of 2 tasks

custom level not work in typescript #1523

cheerfyt opened this issue Nov 2, 2018 · 9 comments
Labels
Docs Applies to Winston's documentation FAQ Frequently Asked Questions

Comments

@cheerfyt
Copy link

cheerfyt commented Nov 2, 2018

Please tell us about your environment:

  • winston version?
    • winston@2
    • winston@3
  • _node -v outputs:_v8.12.0
  • Operating System? macOS
  • Language? | TypeScript 3.1.3

What is the problem?

custom level not work in typescript 3.1.3

code

import winston from 'winston';

const myCustomLevels: winston.config.AbstractConfigSetLevels = {
  foo: 0,
  bar: 1,
  baz: 2,
  foobar: 3
};

const customLevelLogger = winston.createLogger({
  levels: myCustomLevels,
  transports: [
    new winston.transports.Console({
      level: 'foobar'
    })
  ]
});
//  [ts] Property 'foobar' does not exist on type 'Logger'.
customLevelLogger.foobar('some foobar level-ed message');
@sachinh19
Copy link

Facing the same issue. Do we need to define a custom type here or is there some other way how this can be achieved?

@sachinh19
Copy link

sachinh19 commented Nov 6, 2018

So I ended up using Declaration Merging

@types/winston/index.d.ts

import * as winston from 'winston';

declare module 'winston' {
  export interface Logger {
    foobar: winston.LeveledLogMethod;
  }
}

Modified your code

import winston from 'winston';

const myCustomLevels: winston.config.AbstractConfigSetLevels = {
  foo: 0,
  bar: 1,
  baz: 2,
  foobar: 3
};

const customLevelLogger: winston.Logger = winston.createLogger({
  levels: myCustomLevels,
  transports: [
    new winston.transports.Console({
      level: 'foobar'
    })
  ]
});

customLevelLogger.foobar('some foobar level-ed message');

Not sure if this is the best way to work with this, but this works for now.

Waiting to hear if this can be done in a better way.

@cheerfyt
Copy link
Author

cheerfyt commented Nov 6, 2018

@sachinh19 it's work! Thanks for your reply

@jensbodal
Copy link

Another alternative is to just extend the winston.Logger interface and then cast the result of createLogger to your interface.

import winston from 'winston';

const myCustomLevels: winston.config.AbstractConfigSetLevels = {
  foo: 0,
  bar: 1,
  baz: 2,
  foobar: 3
};

interface CustomLevels extends winston.Logger {
  foo: winston.LeveledLogMethod;
  bar: winston.LeveledLogMethod;
  baz: winston.LeveledLogMethod;
  foobar: winston.LeveledLogMethod;
}

const customLevelLogger: CustomLevels = <CustomLevels>winston.createLogger({
  levels: myCustomLevels,
  transports: [
    new winston.transports.Console({
      level: 'foobar'
    })
  ]
});

customLevelLogger.foobar('some foobar level-ed message');

@DABH
Copy link
Contributor

DABH commented Dec 13, 2018

Both of these are nice solutions. Not closing this yet because I think it would be a good idea to get some of these "FAQ"-type issues into some examples somewhere. We don't have any TS-specific examples yet but maybe we can add a typescript folder under examples in the repo. Don't want to lose this knowledge in case anyone asks about this in the future :) . @indexzero any thoughts?

@indexzero indexzero added Docs Applies to Winston's documentation FAQ Frequently Asked Questions labels Jan 26, 2019
@indexzero
Copy link
Member

I am supportive of examples/typescript @DABH

@fennecbutt
Copy link

If only they'd change from declare namespace to declare module...then the module could just be augmented externally. 😢

@evankennedy
Copy link

evankennedy commented Oct 8, 2020

It would be even better if each logger could infer levels from the createLogger call. That means if we exclude certain common levels from the levels config, we will get the proper compile-time error if we try calling that.

For example, we could make it infer the levels in this example:

const logger = winston.createLogger({
  levels: { custom: 0 },
});

// works:
logger.custom('stuff');
logger.log('custom', 'stuff');

// compile error:
logger.info('stuff');
logger.log('info', 'stuff');

I'm happy to work on a PR when I get some free time.


Edit: I realize maybe this can't be done since Winston can be augmented on the fly with .configure() 😫

@dev-opus
Copy link

dev-opus commented Apr 22, 2023

you could check out this answer on StackOverflow. works pretty well for my use case

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Docs Applies to Winston's documentation FAQ Frequently Asked Questions
Projects
None yet
Development

No branches or pull requests

8 participants