I am using the queue lib Bull in TypeScript. Its definition is:
node_modules/@types/bull/index.d.ts
declare const Bull: {
(queueName: string, opts?: Bull.QueueOptions): Bull.Queue;
// something like above
};
declare namespace Bull: {
interface Queue {}
interface Job {}
// some other non-exported interfaces
}
export = Bull
I want to merge the namespace Bull
in my library and use it in another app.
node_modules/myLib/index.d.ts
import { Queue } from 'bull'
declare namespace Bull: {
export interface Queues {}
}
export interface myInterface {
foo: Queue | Bull.Queues
}
export = Bull
myApp/foo.ts
import { Job, Queues } from 'myLib' // Error, 'myLib' has no exported member 'Job'
According to the doc, namespace is a GLOBAL variable, and namespaces of the same name will merge their EXPORTED interfaces. So, how can I merge the namespace Bull
from @types/bull
? Thanks!
Well, the truth is that
@types\bull
is not really declaring a namespace.Well, it is, but just to group a list of related types and export them together as the default export, so, what it really exports are the contents of the namespace, not the namespace itself. That's why you can import
Queue
, and useQueue
and notBull.Queue
, which is what you should have to do ifQueue
truly belonged to a namespace.Besides, I don't know what version of TypeScript you're using, but you shouldn't be able to use
export (...)
andexport = (...)
in the same file. Besides, when you addexport
to a file, it turns into a declaration file for a module, so, in the end, you have a module that exports a namespace as default, and then you can importQueues
frommyLib
, but notJob
, asJob
does not appear anywhere in the file and therefore it is not exported.To be able to merge namespaces in different files, you can't use imports or exports, just declarations, because two modules can never contribute names to the same namespace. By using
export
, you're turning your files into modules, and once you do so, namespaces in them do not belong to the global scope anymore, so even if they have the same names, they really belong to the scope of their own module and do not merge.To do what you're trying to do, you'd have to have:
bull:
myLib:
And now you truly have one namespace with the contents of both declarations:
test.ts:
This way it would work, but, unfortunately, is not what you have. You should define
myLib
as:and then you can use:
or, if you prefer,
But, in any case, you need to import from both
bull
andmyLib
.