美文网首页TypeScript
TypeScript的命名空间

TypeScript的命名空间

作者: 浅忆_0810 | 来源:发表于2020-10-13 00:01 被阅读0次

    在代码量较大的情况下,为了避免各种变量命名相冲突,可以将类似功能的函数、类、接口等放置到命名空间中

    TypeScript中的命名空间中的对象、类、函数等可以通过export暴露出来通过命名空间名.类名等来使用

    这个暴露是暴露在命名空间外,不是将其在模块中暴露出去

    命名空间和模块的区别:

    • 命名空间:内部模块,主要用于组织代码,避免命名冲突

    • 模块:TypeScript的外部模块的简称,侧重代码的复用,一个模块里可能会有多个命名空间

      namespace Validation { // 通过namespace关键词创建一个命名空间
        export interface StringValidator { }
      
        const lettersRegexp = /^[A-Za-z]+$/;
        const numberRegexp = /^[0-9]+$/;
      
        export class LettersOnlyValidator implements StringValidator { // 要在外部使用必须导出
          isAcceptable(s: string) { // 函数内部可以不导出
            return lettersRegexp.test(s);
          }
        }
      
        export class ZipCodeValidator implements StringValidator {
          isAcceptable(s: string) {
            return s.length === 5 && numberRegexp.test(s);
          }
        }
      }
      
      // Some samples to try
      let strings = ["Hello", "98052", "101"];
      
      // 在外界就可以直接通过Validation.StringValidator访问命名空间内部导出的接口
      let validators: { [s: string]: Validation.StringValidator; } = {};
      // 上面接口的意思是一个对象,对象中的每个成员都是有isAcceptable接口方法的实例化对象
      validators["ZIP code"] = new Validation.ZipCodeValidator();
      validators["Letters only"] = new Validation.LettersOnlyValidator();
      
      // Show whether each string passed each validator
      for (let s of strings) {
        for (let name in validators) {
          console.log(`"${s}" - ${validators[name].isAcceptable(s) ? "matches" : "does not match"} ${name}`);
        }
      }
      

    1. 多文件中的命名空间

    1.1 通过exportimpot进行使用

    // module.ts
    export namespace A {
      interface Animal {
        name: string;
        eat(): void;
      }
      export class Dog implements Animal {
        name: string;
        constructor(theName: string) {
          this.name = theName;
        }
        eat(): void {
          console.log(this.name + "吃狗粮");
        }
      }
    }
    
    import { A } from "./module";
    let dog = new A.Dog("狗"); // 传入命名空间
    dog.eat();
    

    1.2 通过三斜线指令引入

    三斜线指令:包含单个XML标签的单行注释,注释的内容会做为编译器指令使用,三斜线引用告诉编译器在编译过程中要引入的额外的文件

    三斜线指令仅可放在包含它的文件的最顶端。 一个三斜线指令的前面只能出现单行或多行注释,这包括其它的三斜线指令。 如果它们出现在一个语句或声明之后,那么它们会被当做普通的单行注释,并且不具有特殊的涵义

    这里只用///<reference path=""/>,其余用法在 TypeScript中文文档 查看

    /// <reference path="..." />指令是三斜线指令中最常见的一种,它用于声明文件间的 依赖,三斜线引用告诉编译器在编译过程中要引入的额外的文件,也就是会引入对应path的文件

    // Validation.ts
    namespace Validation {
      export interface StringValidator {
        isAcceptable(s: string): boolean;
      }
    }
    
    // LettersOnlyValidator.ts
    /// <reference path="Validation.ts" />
    namespace Validation {
      const lettersRegexp = /^[A-Za-z]+$/;
      export class LettersOnlyValidator implements StringValidator {
        isAcceptable(s: string) {
          return lettersRegexp.test(s);
        }
      }
    }
    
    // ZipCodeValidator.ts
    /// <reference path="Validation.ts" />
    namespace Validation {
      const numberRegexp = /^[0-9]+$/;
      export class ZipCodeValidator implements StringValidator {
        isAcceptable(s: string) {
          return s.length === 5 && numberRegexp.test(s);
        }
      }
    }
    
    /// <reference path="Validation.ts" />
    /// <reference path="LettersOnlyValidator.ts" />
    /// <reference path="ZipCodeValidator.ts" />
    
    // Some samples to try
    let strings = ["Hello", "98052", "101"];
    
    // Validators to use
    let validators: { [s: string]: Validation.StringValidator; } = {};
    validators["ZIP code"] = new Validation.ZipCodeValidator();
    validators["Letters only"] = new Validation.LettersOnlyValidator();
    
    // Show whether each string passed each validator
    for (let s of strings) {
      for (let name in validators) {
        console.log(`"${s}" - ${validators[name].isAcceptable(s) ? "matches" : "does not match"} ${name}`);
      }
    }
    

    2. 别名

    别名是另一种简化命名空间操作的方法是使用import q = x.y.z给常用的对象起一个短的名字,不要与用来加载模块的import x = require('name')语法弄混了,这里的语法是为指定的符号创建一个别名

    可以用这种方法为任意标识符创建别名,也包括导入的模块中的对象

    namespace Shapes {
      export namespace Polygons {
        export class Triangle { }
        export class Square { }
      }
    }
    
    import polygons = Shapes.Polygons; // 用 polygons代替Shapes.Polygons,相当于C语言的define
    let sq = new polygons.Square(); // Same as "new Shapes.Polygons.Square()"
    

    并没有使用require关键字,而是直接使用导入符号的限定名赋值。与使用 var相似,但它还适用于类型和导入的具有命名空间含义的符号。 重要的是。对于值来讲,import会生成与原始符号不同的引用,所以改变别名的var值并不会影响原始变量的值

    相关文章

      网友评论

        本文标题:TypeScript的命名空间

        本文链接:https://www.haomeiwen.com/subject/qtappktx.html