Module declares 'X' locally but it is not exported in TS

avatar

Borislav Hadzhiev

Thu Mar 17 20222 min read

banner

Photo by Anthony Fomin

Module declares 'X' locally but it is not exported in TS #

The error "Module declares 'X' locally but it is not exported" occurs when we try to import something from a file that doesn't export it. To solve the error use the export keyword to export the member and import it as import {myValue} from './myFile'.

Here is an example of how the error occurs. This is a file called another-file.ts.

another-file.ts
// 👇️ did not export sum function sum(a: number, b: number) { return a + b; } export const num = 100;

And here is an index.ts file located in the same directory that imports from another-file.ts.

index.ts
// ⛔️ Error: Module '"./another-file"' declares 'sum' // locally, but it is not exported.ts(2459) import { sum } from './another-file'; console.log(sum(50, 50));

The index.ts file tries to import the sum function, but another-file.ts does not export the function.

To solve the error, use the export keyword and export the function from the module.

another-file.ts
// 👇️ export function export function sum(a: number, b: number) { return a + b; } export const num = 100;

Now we are able to import the sum function in the index.ts file.

index.ts
import { sum } from './another-file'; console.log(sum(50, 50)); // 👉️ 100

Note that using the export keyword to export something is the same as exporting the values as an object.

another-file.ts
function sum(a: number, b: number) { return a + b; } const num = 100; // 👇️ export sum and num export { sum, num };

We are able to import the values in our index.ts file in the same way.

index.ts
import { sum, num } from './another-file'; console.log(sum(num, num)); // 👉️ 200

TypeScript uses the concept of modules, in the same way that JavaScript does.

You are also able to export values as a default export.

another-file.ts
function sum(a: number, b: number) { return a + b; } // 👇️ default export export default sum; // 👇️ named export export const num = 100;

Now we can import the default and named export in the following way.

index.ts
// 👇️ default and named import import sum, { num } from './another-file'; console.log(sum(num, num)); // 👉️ 200

Notice that we didn't wrap the default import in curly braces.

The main difference between named and default exports and imports is - you can have multiple named exports per file, but you can only have a single default export.

If you are exporting a variable (or an arrow function) as a default export, you have to declare it on 1 line and export it on the next. You can't declare and default export a variable on the same line.

In my experience, most real world codebases exclusively use named exports and imports, because they make it easier to leverage your IDE for autocompletion and auto-imports.

You also don't have to think about which members are exported with a default or named export.

Use the search field on my Home Page to filter through my more than 1,000 articles.