[Bug]: Incorrect typing in TransformableInfo.message
mazamachi opened this issue · 3 comments
The problem
Current typing of TransformableInfo
is
export interface TransformableInfo {
level: string;
message: string;
[key: string]: any;
}
Lines 7 to 11 in 0062e43
However, message
property can be non-string object in winston.
https://github.com/winstonjs/winston/blob/master/lib/winston/logger.js#L221-L227
Winston declares message as any
in TypeScript.
https://github.com/winstonjs/winston/blob/master/index.d.ts#L81
So the message of TransformableInfo.message
should be more loose, e.g. any
.
Example
This is problematic when writing custom format function. Like
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format((info) => ({
...info,
message: info.message.trim(), // compiles as the `message` type is `string`, but actually it can be `object` or `any`.
}))(),
winston.format.simple(),
),
transports: [new winston.transports.Console()],
});
logger.info(' message\t'); // OK. logs `'info: message'`
logger.info({ foo: 'bar' }); // NG. throws error
// Uncaught TypeError: info.message.trim is not a function
// at Format.transform (...)
// at Format.transform (/.../node_modules/logform/combine.js:20:24)
// at DerivedLogger._transform (/.../node_modules/winston/lib/winston/logger.js:313:29)
And if a user transforms object properly, typescript cannot compile.
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format((info) => ({
...info,
message: typeof info.message === 'string' ?
info.message.trim()
: info.message.toString(),
// ^^^ info.message is `never` here, so toString() does not exist
}))(),
winston.format.simple(),
),
transports: [new winston.transports.Console()],
});
logger.info(' message\t'); // works. logs `'info: message'`
logger.info({ foo: 'bar' }); // works. logs `'info: [object Object]'`
Actually, the example code above cannot be compiled in TypeScript, it can run properly as JavaScript.
What version of Logform presents the issue?
2.4.0
What version of Node are you using?
v14.17.0
If this worked in a previous version of Logform, which was it?
No response
Minimum Working Example
(Same as examples above)
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format((info) => ({
...info,
message: info.message.trim(),
}))(),
winston.format.simple(),
),
transports: [new winston.transports.Console()],
});
logger.info(' message\t'); // OK. logs `'info: message'`
logger.info({ foo: 'bar' }); // NG. throws error
// Uncaught TypeError: info.message.trim is not a function
// at Format.transform (...)
// at Format.transform (/.../node_modules/logform/combine.js:20:24)
// at DerivedLogger._transform (/.../node_modules/winston/lib/winston/logger.js:313:29)
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format((info) => ({
...info,
message: typeof info.message === 'string' ?
info.message.trim()
: info.message.toString(),
// ^^^ info.message is `never` here, so toString() does not exist
}))(),
winston.format.simple(),
),
transports: [new winston.transports.Console()],
});
logger.info(' message\t'); // works. logs `'info: message'`
logger.info({ foo: 'bar' }); // works. logs `'info: [object Object]'`
Additional information
No response
🔎 Search Terms
typescript, message, typing
I just ran into this when trying to create a custom transport for winston in TS. the actual formatted message is stored in a key on the object that is a symbol type, not a string, so TS complains about unique symbols not being allowed as an indexer in this case.
PR welcome!
Will do