如何合并名称空间在TypeScript中没有导出的接口 [英] How to merge namespace has no exported interface in TypeScript

查看:285
本文介绍了如何合并名称空间在TypeScript中没有导出的接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

根据文档,名称空间是GLOBAL变量,并且具有相同名称的名称空间将合并其EXPORTED接口.那么,如何合并@types/bull中的命名空间Bull?谢谢!

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!

推荐答案

好吧,事实是@types\bull并未真正声明名称空间.

Well, the truth is that @types\bull is not really declaring a namespace.

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

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 use Queueand not Bull.Queue, which is what you should have to do if Queue truly belonged to a namespace.

此外,我不知道您使用的是哪个版本的TypeScript,但您不应在同一文件中使用export (...)export = (...).此外,将export添加到文件时,它会变成模块的声明文件,因此,最后,您有一个模块将默认导出名称空间,然后可以从Queues >,而不显示Job,因为Job不会出现在文件中的任何位置,因此不会导出.

Besides, I don't know what version of TypeScript you're using, but you shouldn't be able to use export (...) and export = (...) in the same file. Besides, when you add export 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 import Queues from myLib, but not Job, as Job does not appear anywhere in the file and therefore it is not exported.

要能够将命名空间合并到不同的文件中,不能使用导入或导出,而只能使用声明,因为两个模块永远不能将名称贡献给同一命名空间.通过使用export,您将文件转换为模块,一旦这样做,它们中的名称空间就不再属于全局范围,因此,即使它们具有相同的名称,它们实际上也属于它们的范围.自己的模块,不要合并.

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:

公牛:

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

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

    // some other non-exported interfaces
}

myLib:

declare namespace Bull {
  export interface Queues {}
}

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

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

And now you truly have one namespace with the contents of both declarations:

test.ts:

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

这样可以正常工作,但是,不幸的是,这不是您所拥有的.您应该将myLib定义为:

This way it would work, but, unfortunately, is not what you have. You should define myLib as:

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;

但是,无论如何,您都需要同时从bullmyLib导入.

But, in any case, you need to import from both bull and myLib.

这篇关于如何合并名称空间在TypeScript中没有导出的接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆