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

时间:2018-04-09 02:43:37

标签: 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

我想在我的库中合并名称空间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

对myApp / foo.ts

import { Job, Queues } from 'myLib' // Error, 'myLib' has no exported member 'Job'

根据doc,namespace是一个GLOBAL变量,同名的命名空间将合并它们的EXPORTED接口。那么,如何从Bull合并名称空间@types/bull?谢谢!

1 个答案:

答案 0 :(得分:2)

嗯,事实是@types\bull并没有真正声明命名空间。

嗯,它只是将相关类型列表分组并将它们一起导出为默认导出,因此,它真正导出的是命名空间的内容,而不是命名空间本身。这就是为什么你可以导入Queue,并使用Queue而不是Bull.Queue,这是Queue真正属于命名空间时应该做的。

此外,我不知道您正在使用的TypeScript版本,但您不能在同一文件中使用export (...)export = (...)。此外,当您将export添加到文件时,它会变成模块的声明文件,因此,最后,您有一个模块将默认情况下导出名称空间,然后您可以导入{{1} } Queues,而不是myLib,因为Job不会出现在文件的任何位置,因此不会导出。

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

要做你想做的事,你必须要:

export

MYLIB:

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

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

    // some other non-exported interfaces
}

现在你真的有一个名称空间包含两个声明的内容:

test.ts:

declare namespace Bull {
  export interface Queues {}
}

declare interface myInterface {
  foo: Bull.Queue | Bull.Queues
}

这样可行,但不幸的是,这不是你所拥有的。您应该将const a: Bull.Queues = {}; const g: Bull.Queue = {}; const b: Bull.Job = {}; 定义为:

myLib

然后你可以使用:

import * as Bull from './bull';

export interface Queues {};


export interface myInterface {
  foo: Bull.Queue | Queues;
}

或者,如果您愿意,

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;

但是,无论如何,您需要同时从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; bull导入。