如何合并名称空间在TypeScript中没有导出的接口

Bri*_*ang 5 typescript bull.js

我在TypeScript中使用队列lib Bull。其定义是:

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
Run Code Online (Sandbox Code Playgroud)

我想Bull在我的库中合并命名空间,并在另一个应用程序中使用它。

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
Run Code Online (Sandbox Code Playgroud)

myApp / foo.ts

import { Job, Queues } from 'myLib' // Error, 'myLib' has no exported member 'Job'
Run Code Online (Sandbox Code Playgroud)

根据文档,名称空间是GLOBAL变量,同名名称空间将合并其EXPORTED接口。因此,如何合并Bull来自的命名空间@types/bull?谢谢!

Osc*_*Paz 5

好吧,事实是这@types\bull并不是真正声明名称空间。

嗯,确实如此,但只是将相关类型的列表分组并将它们作为默认导出一起导出,因此,它真正导出的是命名空间的内容,而不是命名空间本身。这就是为什么您可以 import Queue、 useQueue和 not ,如果真正属于某个命名空间,Bull.Queue您应该这样做。Queue

此外,我不知道你正在使用什么版本的 TypeScript,但你不应该在同一个文件中使用export (...)and 。export = (...)此外,当您添加export到文件时,它会变成模块的声明文件,因此,最终,您有一个默认导出命名空间的模块,然后您可以从 导入,但不能导入QueuesmyLib因为Job没有Job出现文件中的任何位置,因此不会导出它。

为了能够合并不同文件中的命名空间,您不能使用导入或导出,而只能使用声明,因为两个模块永远不能向同一命名空间提供名称。通过使用export,您可以将文件转换为模块,一旦这样做,其中的名称空间就不再属于全局范围,因此即使它们具有相同的名称,它们也确实属于自己模块的范围,并且不要合并。

为了做你想做的事,你必须:

公牛:

declare const Bull: {
    (queueName: string, opts?: any): Bull.Queue;
    // something like above
  };

declare namespace Bull {
    interface Queue {}
    interface Job {}

    // some other non-exported interfaces
}
Run Code Online (Sandbox Code Playgroud)

我的库:

declare namespace Bull {
  export interface Queues {}
}

declare interface myInterface {
  foo: Bull.Queue | Bull.Queues
}
Run Code Online (Sandbox Code Playgroud)

现在您真正拥有了一个包含两个声明内容的命名空间:

测试.ts:

const a: Bull.Queues = {};
const g: Bull.Queue = {};
const b: Bull.Job = {};
Run Code Online (Sandbox Code Playgroud)

这样它就可以工作,但不幸的是,这不是你所拥有的。您应该定义myLib为:

import * as Bull from './bull';

export interface Queues {};


export interface myInterface {
  foo: Bull.Queue | Queues;
}
Run Code Online (Sandbox Code Playgroud)

然后你可以使用:

import * as Bull from './bull';
import { Queues, myInterface } from './myLib';

const a: Queues = {};
const g: Bull.Queue = {};
const b: Bull.Job = {};

const instance: myInterface = null;
Run Code Online (Sandbox Code Playgroud)

或者,如果您愿意,

import * as Bull from './bull';
import * as ExtendedBull from './myLib';

const a: ExtendedBull.Queues = {};
const g: Bull.Queue = {};
const b: Bull.Job = {};

const instance: ExtendedBull.myInterface;
Run Code Online (Sandbox Code Playgroud)

但是,无论如何,您都需要从bull和导入myLib