Typescript ambient module declarations
Tags: typescript
Published: 2017-09-24 19:55:16

---
title: Typescript ambient module declarations
published: true
description: Consuming ambient module declarations
tags: TypeScript
canonical_url: https://www.mourtada.se/typescript-ambient-module-declarations/
---

Originally posted at [www.mourtada.se](https://www.mourtada.se/typescript-ambient-module-declarations/)

With ES2015 JavaScript got the concept of modules using the export and import keywords. Typescript supports this and and it all works well as long as you are writing your modules in TypeScript. But to use external libraries or code that is not written in TypeScript you need to have a type declaration. For all major libraries these already exists in the definitelytyped repository which can be queried viaÂ <a href="https://microsoft.github.io/TypeSearch/" target="_blank" rel="noopener">TypeSearch</a>. But sometimes you'll have to write one yourself.

I had some problems understanding how these declaration should be consumed and found the documentation a little bit tricky to understand which made me to write this.
<h2>Ambient modules</h2>
From TypeScript documentation:
<blockquote>We call declarations that don’t define an implementation “ambient”. Typically, these are defined inÂ .d.tsÂ files. If you’re familiar with C/C++, you can think of these asÂ .hÂ files</blockquote>
So to write type declarations for code that is already written in JavaScript we have to write an ambient module. As stated above these are almost always defined in a file ending with a <code>.d.ts</code> extension.

How can we define an ambient module ? There are two ways.
<h3>Global declarations</h3>
When using <code>declare module</code> to create an ambient module the naming of the <code>.d.ts</code> file doesn't matter what's important is that the file is included in the compilation.

```js
declare module "my-module" {
    export const a: number;
    export function b(paramA: number): void;
}
```

When the file above is included in the compilation TypeScript will register that there's a module named <code>my-module</code> which then can be imported

```js
import { a, b } from "my-module"
```

There are different ways to include declaration files in the compilation
<ol>
 	<li>Specify path in the <code>typeRoots</code> compilerOptions inÂ <code>tsconfig.</code>All global declarations files under typeRoots will be automatically included. This can be controlled with the <code>types</code> property compilerOption where you can explicitly control which definitions should be automatically included</li>
 	<li>Specify the files property in <code>tsconfig</code> so that the declaration file is included</li>
 	<li>Use the tripple slash directive <code>/// &lt;reference path="..." /&gt;</code></li>
 	<li>With the help of paths compilerOptions in <code>tsconfig</code></li>
</ol>
From TypeScript documentation
<blockquote>Keep in mind that automatic inclusion is only important if you’re using files with global declarations (as opposed to files declared as modules). If you use anÂ import "foo"Â statement, for instance, TypeScript may still look throughÂ node_modulesÂ &amp;Â node_modules/@typesÂ folders to find theÂ fooÂ package.</blockquote>
<h3>Files declared as modules</h3>
Using top-level export and import module declarations the <code>.d.ts</code> does not need to be included in the compilation. The important thing here is that the file is named <code>index.d.ts</code> and resides in a folder named after the module which in this case is <code>my-module</code>

```js
// index.d.ts
export const a: number;
export function b(paramA: number): void;

// In a file importing the library
import { a, b } from "my-module"
```

What TypeScript will do is by default to try and lookup <code>my-module</code>. It will try with a number of different steps looking for both code(ts files) and declarations(.d.ts files). One of the steps is to look for declaration files in <code>node_modules/@types</code>. It will look for a folder named like the imported module with an index.d.ts file looking like the one above.

Sometimes you don't wan't to publish declaration files to definitelytyped and have folder with custom type declarations and therefore inform TypeScript to look for declarations in other folder than node_modules/@types. This can be done with the help of <code>compilerOption</code> <code>paths</code>.

```js
{
    "baseUrl": ".",
    "paths": {
        "*": [
            "custom-typings/*"
        ]
    }
}
```

With this configuration in <code>tsconfig.json</code> TypeScript will look for code and declaration files in the <code>custom-typings</code> folder.

To verify where TypeScript is trying to resolve things you can run the compiler with the <code>traceresolution</code> flag

```bash
tsc --traceresolution
```