Chris Knight
Chris Knight

Reputation: 25054

Cannot import module

I have the following code:

import {AsyncLock} from 'async-lock';

but tsc is complaining:

[ts] Module '"my_app/node_modules/@types/async-lock/index"' has no exported member 'AsyncLock'.

but if I look at my_app/node_modules/@types/async-lock/index.d.ts I see the following:

interface AsyncLockDoneCallback {
    (err?: Error, ret?: any): void;
}

interface AsyncLockOptions {
    timeout?: number;
    maxPending?: number;
    domainReentrant?: boolean;
    Promise?: any;
}

declare class AsyncLock {
    constructor(options?: AsyncLockOptions);

    acquire(key: string | string[], fn: (done: AsyncLockDoneCallback) 
=> any, cb: AsyncLockDoneCallback, opts?: AsyncLockOptions): void;
    acquire(key: string | string[], fn: (done: AsyncLockDoneCallback) 
=> any, opts?: AsyncLockOptions): PromiseLike<any>;

    isBusy(): boolean;
}

declare namespace AsyncLock { }

export = AsyncLock;

It very much looks to me as if AsyncLock is being exported here. Where am I going wrong with my import definition?

Upvotes: 1

Views: 2310

Answers (1)

Shaun Luttin
Shaun Luttin

Reputation: 141442

Short Answer

When a declaration file exports like this:

export = AsyncLock;

Then we import it in one of these two ways:

import AsyncLock = require("async-lock"); // thank you unional
import * as AsyncLock from "async-lock";

Both support static analysis. (See unional's corrections below in the comments.)

Further Details

From the TypeScript modules documentation:

Both CommonJS and AMD generally have the concept of an exports object which contains all exports from a module.

They also support replacing the exports object with a custom single object. Default exports are meant to act as a replacement for this behavior; however, the two are incompatible. TypeScript supports export = to model the traditional CommonJS and AMD workflow.

What you were trying to use is the more modern style, when a declaration file exports like this:

export { AsyncLock }

In that case, we do import it like this:

import { AsyncLock } from "async-lock";

Upvotes: 1

Related Questions