首页 文章

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

提问于
浏览
4

我在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接口 . 那么,如何从 @types/bull 合并命名空间 Bull ?谢谢!

1 回答

  • 2

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

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

    此外,我没有't know what version of TypeScript you'重新使用,但你不应该在同一个文件中使用 export (...)export = (...) . 此外,当你将 export 添加到一个文件时,它会变成一个模块的声明文件,所以,最后,你有一个模块,默认导出一个命名空间,然后你可以从 myLib 导入 Queues ,但不能导入 Job ,因为 Job 没有出现在文件中的任何位置,因此不会导出 .

    为了能够在不同的文件中合并名称空间,您不能使用导入或导出,只能声明声明,因为 two modules can never contribute names to the same namespace . 通过使用 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
    }
    

    MYLIB:

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

    现在,您确实拥有一个名称空间,其中包含两个声明的内容:

    test.ts:

    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;
    

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

相关问题