compromise_1.default is not a function

Created on 28 Jan 2020  路  11Comments  路  Source: spencermountain/compromise

This is what I did:

npm i ts-node
npm i typescript
npm i compromise

Then I pasted the node module example:

// script.ts
import nlp from 'compromise'

var doc = nlp('London is calling')
doc.verbs().toNegative()

Then did:

ts-node script.ts

And I got this error:

TypeError: compromise_1.default is not a function

The same happened when I was working in a VS Code extension.ts file. (So maybe Compromise has problems running in TypeScript files?). Compromise worked well after I changed import nlp from 'compromise' to const nlp = require('compromise').

Note: These are the versions of the packages.

"compromise": "^12.3.0",
"ts-node": "^8.6.2",
"typescript": "^3.7.5"
Discussion

All 11 comments

Hey @alexcheninfo, I just tested with the same setup and a fresh tsconfig; seems to be working fine on my end. Have you made any changes to your tsconfig?

compromise definitely has a default export, but for now a workaround might be adding "allowSyntheticDefaultImports": true, to your tsconfig

@Drache93 Thanks for helping.

I don't have a tsconfig file in the folder I created to recreate this error.

This is how my tsconfig file looks like in my VS Code extension:

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es6",
    "outDir": "out",
    "lib": [
      "es6"
    ],
    "sourceMap": true,
    "rootDir": "src",
    "strict": true,
    /* enable all strict type-checking options */
    /* Additional Checks */
    // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
    // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
    // "noUnusedParameters": true,  /* Report errors on unused parameters. */
    "allowSyntheticDefaultImports": true // I just added this
  },
  "exclude": [
    "node_modules",
    ".vscode-test"
  ]
}

As you can see, I added allowSyntheticDefaultImports": true, but I'm still getting the same error.

VS Code is also showing another problem. It's in compromise/types/index.d.ts. The error says Cannot find name 'Text'. It's this line:

out(format: 'debug'): Text

Not sure if that has anything to do with the original problem.

No problem! Ah right, just tried your config definitely the problem.

Played around, looks like this boy here fixes your original problem (is included in default tsconfig - tsc --init)

    "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */

@Drache93 That did it. Thanks, this problem had been bugging me for a while!

@alexcheninfo Glad I could help!

Is setting esModuleInterop really necessary? I use a whole bunch of library's with default exports, but I import them as import * as lib from 'library'. I can't currently do this with compromise because then the types don't line up. It's kind of annoying that this is the only library I have to enable esModuleInterop for and then have to change existing imports for the other libraries with default exports.

Hi @twgraham thanks for the feedback.
Compromise does have a default export so I can look into why typescript seems to have a problem with it (aka why es modules is required). Since esModulesInterop is default I assumed it was safe.

What's the effect on your other libraries? * import doesn't work the same?
Compromise is the only library I've seen that namespaces the types and overlaps that namespace with the default export... probably worth changing this to just direct exports so they can be used with asterisk or deconstruction - that said, compromise has lots of classes that we want the types, but the constructor is never exported, hence the use of a namespace.

Could we reopen this please @spencermountain ?

Sorry for the delay in responding @Drache93. Don't mind me, just having a whinge. esModuleInterop isn't the default, but I found out it is recommended. It is default if you use something like babel-loader to compile your typescript though.

The issue I saw was that all existing star imports would fail when esModuleInterop was enabled e.g. import * as React from 'react' import * as cx from 'classnames' etc.

Compromise is the only library I've seen that namespaces the types and overlaps that namespace with the default export... probably worth changing this to just direct exports so they can be used with asterisk or deconstruction

I don't really want to suggest rewriting your types, especially when the solution suggested is the recommended solution by TS themselves. I'll suck it up and rewrite all my imports 馃憤

@Drache93

I'm getting this error:

$ tsc -p .
node_modules/compromise/types/index.d.ts:315:27 - error TS2304: Cannot find name 'Text'.

315     out(format: 'debug'): Text

when doing:

import nlp from "compromise";

With the following in my tsconfig.json:

"allowSyntheticDefaultImports": true,
"esModuleInterop": true 

Am I missing something?

If I change the relevant types file to have:

out(format: 'debug'): string[]

Everything works fine.

Ah nice find. Looks like Text was a bad type - actually a built in one so it passed tests!
.out('debug') and .debug() both return your Document.

Fixed here: https://github.com/spencermountain/compromise/pull/749

@Drache93 Ah great, thanks!

Was this page helpful?
0 / 5 - 0 ratings