Node.js TypeScript Winston报错:TS2339 TransformableInfo无metadata属性
Winston TypeScript TS2339: Property 'metadata' 不存在于 TransformableInfo 类型的问题
问题场景
同一段Winston日志配置代码在一个Node.js TypeScript项目中运行正常,但在另一个依赖版本、Node版本完全一致的项目中,出现TS2339错误,提示metadata属性不存在于TransformableInfo类型。已尝试升级Winston版本至3.7.1、3.8.2,问题仍未解决。
正常运行的Winston配置代码
const format_string_console = combine( format.errors({ stack: true }), timestamp({ format: timezonedTime }), format.ms(), format.metadata(), format.colorize({ all: true }), winston.format.printf( info => `${info.metadata.timestamp} ${info.metadata.ms} ${info.metadata.host} pid:${process.pid} ` + `${info.level}: ${info.message}`, ), ); // ...其他代码 const Logger = winston.createLogger({ level: 'debug', // 显示debug及以下级别日志 levels, defaultMeta: { service: 'whale', host: os.hostname() }, transports, });
报错信息
ubuntu@ip-172-31-43-104:~/myapp/worker$ nodemon --exec ts-node --files src/index.ts [nodemon] 2.0.20 [nodemon] to restart at any time, enter `rs` [nodemon] watching path(s): *.* [nodemon] watching extensions: ts,json [nodemon] starting `ts-node --files src/index.ts` /home/ubuntu/myapp/worker/node_modules/ts-node/src/index.ts:859 return new TSError(diagnosticText, diagnosticCodes, diagnostics); ^ TSError: ⨯ Unable to compile TypeScript: src/utils/logger/devLogger.ts:48:15 - error TS2339: Property 'metadata' does not exist on type 'TransformableInfo'. 48 `${info.metadata.timestamp} ${info.metadata.ms} ${info.metadata.host} pid:${process.pid} ` + ~~~~~~~~ # 省略重复报错行 src/utils/logger/devLogger.ts:87:67 - error TS2339: Property 'metadata' does not exist on type 'TransformableInfo'. 87 return `${info.metadata.timestamp} ${moment(parseFloat(info.metadata.timestamp))} `; ~~~~~~~~ at createTSError (/home/ubuntu/myapp/worker/node_modules/ts-node/src/index.ts:859:12) # 省略报错堆栈 [nodemon] app crashed - waiting for file changes before starting...
解决方法
1. 类型断言快速修复
在printf的回调函数中,对info参数使用类型断言,明确其包含metadata属性:
winston.format.printf( (info: TransformableInfo & { metadata: { timestamp: string; ms: string; host: string } }) => `${info.metadata.timestamp} ${info.metadata.ms} ${info.metadata.host} pid:${process.pid} ` + `${info.level}: ${info.message}`, ),
如果需要更灵活的结构,也可以用info as any,但不推荐长期使用,会丢失类型检查优势。
2. 扩展Winston全局类型(推荐)
创建自定义类型声明文件,扩展Winston的TransformableInfo类型,让TypeScript识别metadata属性:
- 在项目中创建
src/@types/winston/index.d.ts文件,内容如下:
import 'winston'; declare module 'winston' { interface TransformableInfo { metadata: { timestamp: string; ms: string; host: string; // 可根据需求添加其他属性 [key: string]: any; }; } }
- 修改
tsconfig.json,确保类型目录被识别:
{ "compilerOptions": { // 其他配置 "typeRoots": ["./src/@types", "./node_modules/@types"] } }
这种方式一劳永逸,整个项目都会识别到metadata属性。
3. 检查format执行顺序
确保format.metadata()在printf之前执行,虽然你已经这么做了,但如果存在其他format干扰,可能导致类型推断失效。可以尝试调整format顺序,确保metadata是在printf之前的最后几个步骤之一。
问题根源
Winston的默认类型定义中,TransformableInfo并不包含metadata属性——这个属性是由format.metadata()这个格式化器动态添加的,TypeScript无法自动推断出这个运行时添加的属性,因此需要手动扩展类型或使用断言来让编译器识别。
内容的提问来源于stack exchange,提问作者Kid_Learning_C
相关产品推荐
相关产品推荐

