newrelic / newrelic-winston-logenricher-node

This is no longer maintained. The work has been moved to https://github.com/newrelic/newrelic-node-log-extensions/tree/main/packages/winston-log-enricher
Apache License 2.0
6 stars 8 forks source link

Typescript compiling error in 2.1.0 #63

Closed alvarolimajr closed 2 years ago

alvarolimajr commented 2 years ago

I've updated version 2.0.0 to 2.1.0 and now I'm getting a typescript error.

Description

I've updated version 2.0.0 to 2.1.0 and now I'm getting a typescript error TS2349: This expression is not callable. Type 'typeof import("/.../node_modules/@newrelic/winston-enricher/types/index")' has no call signatures.

Expected Behavior

Work like version 2.0.0

Steps to Reproduce

import * as newrelicFormatter from '@newrelic/winston-enricher';

// Use in winston format
format: winston.format.combine(
  winston.format.label({label: 'test'}),
  newrelicFormatter() // error TS2349: This expression is not callable.
)

// This import work fine
// const newrelicFormatter = require('@newrelic/winston-enricher')
// format: winston.format.combine(
//  winston.format.label({label: 'test'}),
//  newrelicFormatter()
//)

Your Environment

tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "es2017",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "resolveJsonModule": true
  }
}
michaelgoin commented 2 years ago

Hi @alvarolimajr,

I'm surprised that worked previously, as I expect the output would have been an object { default: createFormatWrap } which would end up with logEnricher is not a function at runtime. Perhaps this is differing behavior based on a particular TypeScript version. I'd guess you are on older than 4.4.4?

To resolve the issue, change your import to:

import newrelicFormatter from '@newrelic/winston-enricher'; and everything should work as expected.

alvarolimajr commented 2 years ago

Hi @alvarolimajr,

I'm surprised that worked previously, as I expect the output would have been an object { default: createFormatWrap } which would end up with logEnricher is not a function at runtime. Perhaps this is differing behavior based on a particular TypeScript version. I'd guess you are on older than 4.4.4?

To resolve the issue, change your import to:

import newrelicFormatter from '@newrelic/winston-enricher'; and everything should work as expected.

Hi @michaelgoin,

I'm using version 4.5.x of the typescript (exactly version 4.5.3)

I tried to use:

import { default as newrelicFormatter } from '@newrelic/winston-enricher';
---
newrelicFormatter();

And I got the error: UnhandledPromiseRejectionWarning: TypeError: (0 , winston_enricher_1.default) is not a function

and I tried:

import newrelicFormatter from '@newrelic/winston-enricher';
---
newrelicFormatter();

And I got the same error: UnhandledPromiseRejectionWarning: TypeError: (0 , winston_enricher_1.default) is not a function

What should I do? (Right now I'm using the 2.0.0 version and its work fine)

michaelgoin commented 2 years ago

I wasn't able to reproduce this until using your exact settings.

It looks like you need "esModuleInterop": true, because this is a commonJS module export. For some reason allowSyntheticDefaultImports results in not getting the warning but has the broken behavior.

Without either, you get the warning:

193 export = winston;
        ~~~~~~~~~~~~~~~~~
    This module is declared with using 'export =', and can only be used with a default import when using the 'esModuleInterop' flag.

Including both, everything seems to be working fine.

{
  "compilerOptions": {
      "module": "commonjs",
      "esModuleInterop": true,
      "declaration": true,
      "removeComments": true,
      "emitDecoratorMetadata": true,
      "experimentalDecorators": true,
      "allowSyntheticDefaultImports": true,
      "target": "es2017",
      "sourceMap": true,
      "outDir": "./dist",
      "baseUrl": "./",
      "incremental": true,
      "resolveJsonModule": true
  }
}
michaelgoin commented 2 years ago

So basically, I think our defining of the type as a default export resulted in some awkwardness with your setup. I think we did that based on the behavior we had been seeing although we may have always been testing with "esModuleInterop": true which may have forced the default export regardless.

alvarolimajr commented 2 years ago

I wasn't able to reproduce this until using your exact settings.

It looks like you need "esModuleInterop": true, because this is a commonJS module export. For some reason allowSyntheticDefaultImports results in not getting the warning but has the broken behavior.

Without either, you get the warning:

193 export = winston;
        ~~~~~~~~~~~~~~~~~
    This module is declared with using 'export =', and can only be used with a default import when using the 'esModuleInterop' flag.

Including both, everything seems to be working fine.

{
  "compilerOptions": {
      "module": "commonjs",
      "esModuleInterop": true,
      "declaration": true,
      "removeComments": true,
      "emitDecoratorMetadata": true,
      "experimentalDecorators": true,
      "allowSyntheticDefaultImports": true,
      "target": "es2017",
      "sourceMap": true,
      "outDir": "./dist",
      "baseUrl": "./",
      "incremental": true,
      "resolveJsonModule": true
  }
}

I added "esModuleInterop": true and it worked fine now. Thanks for your help.

coreyarnold commented 2 years ago

Glad you got things sorted out!

kimmanwky commented 2 years ago

I got the same issue. I tried adding esModuleInterop: true, but it will cause hundreds more other errors in my code. I don't think this is the proper solution. Please advice.