Typescript:在另一个模块的类上添加方法/从不同的模块中填充命名空间

时间:2015-12-24 06:22:23

标签: node.js module typescript commonjs partial-classes

故事

我正在构建一个用于数学运算的模块化库。我还想将库分成多个模块:corerelationalvectors,依此类推。这些模块可以单独使用(但都取决于core模块)

  1. 我知道不可能使用部分类How do I split a TypeScript class into multiple files? / https://github.com/Microsoft/TypeScript/issues/563
  2. 问题:

    core模块定义Set类,这是一个数学集。它定义了Set#addSet#remove等操作。

    但是,可选 relational模块会在Set#product类上添加Set运算符。

    其他模块也可以在Set类上添加其他操作。我希望在我认为合适的时候保留添加功能的可能性。

    问题

    1. 使用 typescript ,如何在位于另一个模块中的类上添加方法?

    2. 如何安排打字输入,以便我的图书馆用户只有在安装了Set#product模块后,才会在代码完成中看到relational?否则,他只会看到#add#remove操作?

    3. 我正在为node.js开发此库,但也使用browserify将其捆绑以供浏览器使用。

      // core/set.ts 
      
      export class Set {
        add(element){}
        remove(element){}
      }
      
      
      // relational/set.ts
      
      import {Set} from './../core/set.ts';
      
      Set.prototype.product = function(){} // ?
      
      
      // app/index.js
      
      import {core} from 'mylib';
      
      var set = new Set();
      set.add();
      set.remove();
      // set.product() is not available
      
      
      // app/index2.js
      
      import {core} from 'mylib';
      import {relational} from 'mylib';
      
      var set = new Set();
      set.add();
      set.remove();
      set.product() //is available

      奖金问题

      所有这些模块都可以通过公共名称空间使用,我们称之为MyLibrarycore模块添加MyLibrary.Corerelational模块将一些对象添加到MyLibrary.Core,并添加MyLibrary.Relational

      假设我发布了另一个模块,仅用作其他模块的外观。我们将此模块称为my-library

      如果用户使用npm安装my-librarycorerelational模块。

      npm install my-library && npm install core and nom-install relational
      

      在客户端应用程序中,我希望库的用户只需编写

      var lib = require('my-library');
      

      然后,my-library会自动检查所有已安装的MyLibrary模块,需要它们并填充MyLibrary名称空间并返回它。

      如何在节点和浏览器环境中告诉my-library模块,第一次访问它

      1. 检查是否有任何可用的MyLibrary模块(浏览器和节点环境)
      2. 为每个模块运行一个方法(将它们安装在命名空间中)
      3. 返回那个漂亮的水果名称空间

1 个答案:

答案 0 :(得分:1)

如果您只是编写声明文件,则可以使用接口代替moment-timezone执行的操作。

moment.d.ts

declare module moment {
    interface Moment {
        // ...
    }

    interface MomentStatic {
        // ...
    }
}
declare module 'moment' {
    var _tmp: moment.MomentStatic;
    export = _tmp;
}

矩timezone.d.ts

只需使用额外功能重新声明相同的接口。

declare module moment {
    interface Moment {
        tz(): void;
    }

    interface MomentStatic {
        tz(): void;
    }
}
declare module 'moment-timezone' {
    var _tmp: moment.MomentStatic;
    export = _tmp;
}

现在两个包都是相同的,moment会自动获取新方法。