typescript declare third party modules
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';
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).
Update for TypeScript 2.7+
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();
Older workaround
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.