美文网首页
声明合并

声明合并

作者: 竹林_ | 来源:发表于2019-10-16 11:53 被阅读0次

    介绍

    指编译器将针对同一个名字的两个独立声明合并为单一声明,合并后的声明同时拥有原先两个声明的特性

    注:任何数量的声明都可被合并

    // 两个相同的接口会进行合并
    interface Box {
      height: number;
      width: number;
    }
    interface Box {
      scale: number;
    }
    let box: Box = {height: 5, width: 6, scale: 10};
    console.log(box)
    

    TS的声明会创建以下三种实体之一:

    • 命名空间:会创建一个新的命名空间,他包含了用(.)符号来访问时使用的名字
    • 类型:用声明的模型创建一个类型并绑定到给定的名字上
    • 值:会创建在JS输出中看到的值

    合并接口:最简单也是最常见的合并类型是接口合并,合并机制是:把双方的成员放到一个同名的接口里

    注意事项:

    • 接口的非函数成员应该是唯一的,如果不是唯一的那么他们必须是相同的类型,否则会报错
    • 对于函数成员,每个同名函数声明都会被当成这个函数的一个重载,注:同名接口后面的接口具有更高的优先级
    // 同名接口后面的接口具有更高的优先级
    interface Animal {}
    interface Sheep {}
    interface Dog {}
    interface Cat {}
    interface Cloner {
      clone(animal: Animal): Animal;
    }
    interface Cloner {
      clone(animal: Sheep): Sheep;
    }
    interface Cloner {
      clone(animal: Dog): Dog;
      clone(animal: Cat): Cat;
    }
    // 合并后
    interface Cloner {
      clone(animal: Dog): Dog;
      clone(animal: Cat): Cat;
      clone(animal: Sheep): Sheep;
      clone(animal: Animal): Animal;
    }
    

    例外:当出现特殊的函数签名时,如果签名里有一个参数的类型是单一的字符串字面量,那么他将被提升到重载列表的最顶端

    // 例外
    interface Document {
      createElement(tagName: any): Element;
    }
    interface Document {
      createElement(tagName: 'div'): HTMLDivElement;
      createElement(tagName: 'span'): HTMLSpanElement;
    }
    interface Document {
      createElement(tagName: string): HTMLElement;
      createElement(tagName: "canvas"): HTMLCanvasElement;
    }
    // 合并后
    interface Document {
      createElement(tagName: "canvas"): HTMLCanvasElement;
      createElement(tagName: "div"): HTMLDivElement;
      createElement(tagName: "span"): HTMLSpanElement;
      createElement(tagName: string): HTMLElement;
      createElement(tagName: any): Element;
    }
    

    合并命名空间

    与接口相似,同名的命名空间也会合并其成员

    • 对于命名空间的合并,模块导出的同名接口进行合并,构成单一命名空间内含合并后的接口
    • 对于命名空间值得合并,如果当前已经存在给定名字的命名空间,那么后来的命名空间的导出成员会被加到已经存在的那个模块里
    • 对于非导出成员的合并,合并后从其他命名空间合并进来的成员无法访问非导出成员
    namespace Animals {
      export class Zebra {}
    }
    namespace Animals {
      export interface Legged { numberOfLegs: number; }
      export class Dog {}
    }
    // 合并后
    namespace Animals {
      export interface Legged { numberOfLegs: number; };
      export class Zebra { }
      export clasas Dog { }
    }
    
    // 对于非导出成员
    namespace Animal {
      let haveMuscles = true;
    
      export function animalsHaveMuscles() {
          return haveMuscles;
      }
    }
    // doAnimalsHaveMuscles函数虽是合并命名空间的一部分,但是访问不了未导出的成员
    namespace Animal {
      export function doAnimalsHaveMuscles() {
          // return haveMuscles;  // Error, because haveMuscles is not accessible here
      }
    }
    

    相关文章

      网友评论

          本文标题:声明合并

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