Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly "declare" a module? (TS7016)

Tags:

typescript

First, here's my tsconfig.json:

{
    "compilerOptions": {
        "strict": true,
        "importHelpers": false,
        "inlineSources": true,
        "noEmitOnError": true,
        "pretty": true,
        "module": "commonjs",
        "noImplicitAny": true,
        "suppressImplicitAnyIndexErrors": false,
        "removeComments": true,
        "preserveConstEnums": false,
        "sourceMap": true,
        "lib": ["es2017","esnext.asynciterable"],
        "skipLibCheck": true,
        "outDir": "dist",
        "target": "es2018",
        "declaration": true,
        "types" : ["node"],
        "resolveJsonModule": true,
        "esModuleInterop": false
    },
    "files": [
        "src/DatabaseWrapper"
    ],
    "exclude": [
        "node_modules"
    ]
}

Now I've tried to import a JavaScript library:

 import Napi from '@org/napi-js';

And I get this error:

TS7016: Could not find a declaration file for module 'napi-js'. '/home/mpen/Projects/my-project/node_modules/@org/napi-js/dist/index.js' implicitly has an 'any' type. Try npm install @types/org__napi-js if it exists or add a new declaration (.d.ts) file containing `declare module 'org__napi-js';

The @types/org__napi-js doesn't exist, so that's no good. So how do I properly declare it?

I've tried creating a file, types/org__napi-js.d.ts' with just this in it:

declare module 'org__napi-js';

And then I tried updating my tsconfig.json so it can find it:

{
    "compilerOptions": {
        ...
        "baseUrl": "./",
        "paths": {
            "*": ["types/*"]
        }
    },
    ...

But that didn't help any.

What am I supposed to do? Or, more explicitly:

  1. How do I tell TypeScript where to find my module?
  2. What's the minimum amount of code that needs to go in this module to just say the default export is any?

I think I want to put all these stubs in types/, and my source in src/ unless there's some standard way to organize a TS project.

like image 207
mpen Avatar asked Aug 01 '18 17:08

mpen


2 Answers

An alternative to creating an empty declaration is ts-ignore:

// @ts-ignore
import Napi from '@org/napi-js';
like image 105
Bryan Larsen Avatar answered Oct 16 '22 12:10

Bryan Larsen


OK, so through a lot of trial and error, it turns out TypeScript is lying about wanting a module called org__napi-js, what it really wants is @org/napi-js.

And, if you're unfamiliar with how paths works as I was, TypeScript looks up the file as its needed based on the module name, so the paths must match, and that includes the @org directory.

So, I was on the right track by updating my tsconfig.json:

{
    "compilerOptions": {
        ...
        "baseUrl": ".",
        "paths": {
            "*": ["types/*"]
        }
    },

That says look in the types dir for modules.

Then create the module file, types/@org/napi-js.d.ts. All it needs is:

declare module '@org/napi-js';

Note how it does include the @namespace/.

That's it. Your project should compile now.

like image 21
mpen Avatar answered Oct 16 '22 14:10

mpen