How could I declare a third party module which looks like this:
in third party module:
module.exports = function foo(){
// do somthing
}
in my code:
import * as foo from 'foo-module'; // Can not find a declaration module for ...
foo();
In TypeScript, just as in ECMAScript 2015, any file containing a top-level import or export is considered a module. Conversely, a file without any top-level import or export declarations is treated as a script whose contents are available in the global scope (and therefore to modules as well).
The error "Could not find declaration file for module" occurs when TypeScript cannot find the type declaration for a module. To solve the error, install the types for the module by running the command from the error message, e.g. npm install -D @types/module-name .
Check out the documentation on working with 3rd party modules.
How to write the declaration depends a lot on how the module was written and what it exports.
The example you've given is a CommonJS module (module.exports = ...
) which is not really a valid ES6 module, because ES6 cannot export a function as the module (it can only export function members or a default function).
With the added esModuleInterop
compiler option you no longer need to use the "namespace hack" shown below for CommonJS modules that have a non-ES6 compatible export.
First, make sure you've enabled esModuleInterop
in your tsconfig.json
(which is now included by default with tsc --init
):
{
"compilerOptions" {
...
"esModuleInterop": true,
...
}
}
Declare your foo-example
in a .d.ts
file like this:
declare module "foo-module" {
function foo(): void;
export = foo;
}
Now you can import it as a namespace like you wanted:
import * as foo from "foo-module";
foo();
Or as a default import:
import foo from "foo-module";
foo();
You can declare your foo-example
in a .d.ts
file like this:
declare module "foo-module" {
function foo(): void;
namespace foo { } // This is a hack to allow ES6 wildcard imports
export = foo;
}
And import like you wanted:
import * as foo from "foo-module";
foo();
Or like this:
import foo = require("foo-module");
foo();
The documentation has a good resource on declaration files and some templates for various kinds of declaration files.
I had a similar problem. And struggled to add a type definition to my project. Finally, I was able to achieve it using the following steps.
This is some module (just with constants), lets call it some-module
- node_modules/some-module/index.js.
'use strict';
exports.__esModule = true;
var APPS = exports.APPS = {
ona: 'ona',
tacq: 'tacq',
inetAcq: 'inetAcq'
};
First I add to tsconfig.json baseUrl
and typeRoots
{
...
"compilerOptions": {
...
"baseUrl": "types",
"typeRoots": ["types"]
}
...
}
Second in my project root I create folder types
with same folders structure for the module types/some-module/index.js
and place the code:
declare module 'some-module' {
type Apps = {
ona: string;
tacq: string;
inetAcq: string;
};
let APPS: Apps
}
Finally I can import it in my my-file.ts
with typings!
import { APPS } from 'some-module';
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With