技术分享

使用TypeScript开发微信小程序(9)——命名空间(Namespace)


TypeScript里,可以使用命名空间(之前叫做“内部模块”,现在叫做“命名空间”)来组织你的代码。

命名空间

Validation.ts

    export interface StringValidator {
        isAcceptable(s: string): boolean;
    }

LettersOnlyValidator.ts

    import { StringValidator } from "./Validation";    const lettersRegexp = /^[A-Za-z]+$/;

    export class LettersOnlyValidator implements StringValidator {
        isAcceptable(s: string) {            return lettersRegexp.test(s);
        }
    }

ZipCodeValidator.ts

    import { StringValidator } from "./Validation";    const numberRegexp = /^[0-9]+$/;    class ZipCodeValidator implements StringValidator {
        isAcceptable(s: string) {        
            return s.length === 5 && numberRegexp.test(s);
        }
    }
    export { ZipCodeValidator };
    export { ZipCodeValidator as mainValidator };
    /// <reference path="Validation.ts" />    /// <reference path="LettersOnlyValidator.ts" />    /// <reference path="ZipCodeValidator.ts" />    let strings = ["Hello", "98052", "101"];      
    let validators: { [s: string]: Validation.StringValidator; } = {};
    validators["ZIP code"] = new Validation.ZipCodeValidator();
    validators["Letters only"] = new Validation.LettersOnlyValidator();       
    strings.forEach(s => {        for (let name in validators) {            console.log("\"" + s + "\"" + (validators[name].isAcceptable(s) ? " matches " : " does not match ") + name);
        }
    });

别名

简化命名空间操作的方法是别名,使用 import q = x.y.z 给常用的对象起一个短的名字,可以用这种方法为任意标识符创建别名,也包括导入的模块中的对象。

    namespace Shapes {
        export namespace Polygons {
            export class Triangle { }
            export class Square { }
        }
    }

    import polygons = Shapes.Polygons;    let sq = new polygons.Square();

使用其它的JavaScript库

为了描述不是用TypeScript编写的类库的类型,需要声明类库导出的 API。 由于大部分程序库只提供少数的顶级对象,命名空间是用来表示它们的一个好办法。

D3.d.ts

    declare namespace D3 {
        export interface Selectors {
            select: {
                (selector: string): Selection;
                (element: EventTarget): Selection;
            };
        }

        export interface Event {
            x: number;
            y: number;
        }

        export interface Base extends Selectors {
            event: Event;
        }
    }

    declare let d3: D3.Base;

命名空间和模块

在TypeScript 里,可以使用模块与命名空间来组织代码的方法。

使用命名空间

命名空间是位于全局命名空间下的一个普通的带有名字的 JavaScript 对象,这令命名空间十分容易使用。 它们可以在多文件中同时使用,并通过 —outFile 结合在一起。 命名空间是组织 Web 应用不错的方式,但就像其它的全局命名空间污染一样,它很难去识别组件之间的依赖关系,尤其是在大型的应用中。

使用模块

像命名空间一样,模块可以包含代码和声明。 不同的是模块可以 声明它的依赖。模块会把依赖添加到模块加载器上(例如 CommonJs / Require.js)。 对于小型的 Web 应用来说可能没必要,但是对于大型应用,这一点点的花费会带来长久的模块化和可维护性上的便利。 模块也提供了更好的代码重用,更强的封闭性以及更好的使用工具进行优化。

从ECMAScript 2015开始,模块成为了语言内置的部分,应该会被所有正常的解释引擎所支持。 因此,对于新项目来说推荐使用模块做为组织代码的方式。

参考资料

  • TypeScript官网
  • TypeScript中文网

其他

  • 完整代码:https://github.com/guyoung/GyWxappCases/tree/master/TypeScript
  • 微信小程序Canvas增强组件WeZRender:https://github.com/guyoung/WeZRender