Reputation: 752
I'm attempting to create a typings file for this simple queue implementation.
In my TS project, I've created a folder called customTypings
and pointed to it in the typeRoots
property of my tsconfig.json file.
Here's what my .d.ts file looks like:
declare module 'queue-fifo' {
export default class Queue {
constructor();
isEmpty(): boolean;
size(): number;
clear(): void;
enqueue(data: any): void;
dequeue(): any;
peek(): any;
}
}
I import is as: import Queue from 'queue-fifo';
And then I try to create an instance of the Queue
class: const queue = new Queue();
At this point, I get no type errors in VS Code, nor do I get any compilation errors. However, when I try to run my code through the debugger, I get:
Exception has occurred: TypeError
TypeError: queue_fifo_1.default is not a constructor
at BinarySearchTree.bfs (/../binarySearchTree.ts:110:23)
at testBst (/../binarySearchTree.ts:139:10)
at Object.<anonymous> (/../binarySearchTree.ts:144:1)
at Module._compile (module.js:632:14)
at Object.Module._extensions..js (module.js:646:10)
at Module.load (module.js:554:32)
at tryModuleLoad (module.js:497:12)
at Function.Module._load (module.js:489:3)
at Function.Module.runMain (module.js:676:10)
at startup (bootstrap_node.js:187:16)
If I break at that line, I see the Queue
(what I imported) is undefined, but queue_fifo_1
is defined, and I can create an instance of the class using that name while in the debug console.
Can someone explain what I'm doing wrong in my declaration/consumption of the declaration that is causing this undesired behavior?
Upvotes: 4
Views: 6253
Reputation: 52133
The queue-fifo
module uses CommonJS-style export = Queue
, which is not compatible with ES6 imports, and gives you no default export. The correct type definition will need to use the same export =
style syntax:
declare module "queue-fifo" {
class Queue {
isEmpty(): boolean;
size(): number;
// etc
}
export = Queue;
}
Which can be imported using CommonJS-style import:
import Queue = require("queue-fifo");
const queue = new Queue();
If you're wondering if it's possible to import this module using ES6 syntax, you can probably use the namespace definition hack:
class Queue { /* ... */ }
namespace Queue { /* empty */ }
export = Queue;
Then import it using ES6 wildcard:
import * as Queue from "queue-fifo";
const queue = new Queue();
But this will only work in non-ES6 environments, for example bundlers like Webpack and Rollup make this work today, but future ES6 compliant module systems will not be able to make this work. See more here: What does "... resolves to a non-module entity and cannot be imported using this construct" mean?
Upvotes: 7