winston version?_winston@2winston@3 node -v outputs:_v8.12.0custom level not work in typescript 3.1.3
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');
Facing the same issue. Do we need to define a custom type here or is there some other way how this can be achieved?
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.
@sachinh19 it's work! Thanks for your reply
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');
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?
I am supportive of examples/typescript @DABH
If only they'd change from declare namespace to declare module...then the module could just be augmented externally. 馃槩
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() :tired_face:
Most helpful comment
Another alternative is to just extend the
winston.Loggerinterface and then cast the result ofcreateLoggerto your interface.