版权

文章转载自:https://github.com/zhongsp

建议您直接跳转到上面的网址查看最新版本。

介绍

TypeScript有一些独特的概念,有的是因为我们需要描述JavaScript顶级对象的类型发生了哪些变化。 这其中之一叫做声明合并。 理解了这个概念,对于你使用TypeScript去操作现有的JavaScript来说是大有帮助的。 同时,也会有助于理解更多高级抽象的概念。

首先,在了解如何进行声明合并之前,让我们先看一下什么叫做声明合并

在这个手册里,声明合并是指编译器会把两个相同名字的声明合并成一个单独的声明。 合并后的声明同时具有那两个被合并的声明的特性。 声明合并不限于只合并两个,任意数量都可以。

基础概念

Typescript中的声明会创建以下三种实体之一:命名空间,类型或者值。 用于创建命名空间的声明会新建一个命名空间:它包含了可以用(.)符号访问的一些名字。 用于创建类型的声明所做的是:用给定的名字和结构创建一种类型。 最后,创建值的声明就是那些可以在生成的JavaScript里看到的那部分(比如:函数和变量)。

Declaration Type Namespace Type Value
Namespace X   X
Class   X X
Interface   X  
Function     X
Variable     X

理解每个声明创建了什么,有助于理解当声明合并时什么东西被合并了。

理解了每种声明会对应创建什么对于理解如果进行声明合并是有帮助的。

合并接口

最简单最常见的就是合并接口,声明合并的种类是:接口合并。 从根本上说,合并的机制是把各自声明里的成员放进一个同名的单一接口里。

interface Box {
height: number;
width: number;
} interface Box {
scale: number;
} var box: Box = {height: 5, width: 6, scale: 10};

接口中非函数的成员必须是唯一的。如果多个接口中具有相同名字的非函数成员就会报错。

对于函数成员,每个同名函数声明都会被当成这个函数的一个重载。

需要注意的是,接口A与它后面的接口A(把这个接口叫做A')合并时,A'中的重载函数具有更高的优先级。

如下例所示:

interface Document {
createElement(tagName: any): Element;
}
interface Document {
createElement(tagName: string): HTMLElement;
}
interface Document {
createElement(tagName: "div"): HTMLDivElement;
createElement(tagName: "span"): HTMLSpanElement;
createElement(tagName: "canvas"): HTMLCanvasElement;
}

这三个接口合并成一个声明。 注意每组接口里的声明顺序保持不变,只是靠后的接口会出现在它前面的接口声明之前。

interface Document {
createElement(tagName: "div"): HTMLDivElement;
createElement(tagName: "span"): HTMLSpanElement;
createElement(tagName: "canvas"): HTMLCanvasElement;
createElement(tagName: string): HTMLElement;
createElement(tagName: any): Element;
}

合并命名空间

与接口相似,同名的命名空间也会合并其成员。 命名空间会创建出命名空间和值,我们需要知道这两者都是怎么合并的。

命名空间的合并,模块导出的同名接口进行合并,构成单一命名空间内含合并后的接口。

值的合并,如果当前已经存在给定名字的命名空间,那么后来的命名空间的导出成员会被加到已经存在的那个模块里。

Animals声明合并示例:

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 class Dog { }
}

除了这些合并外,你还需要了解非导出成员是如何处理的。 非导出成员仅在其原始存在于的命名空间(未合并的)之内可见。这就是说合并之后,从其它命名空间合并进来的成员无法访问非导出成员了。

下例提供了更清晰的说明:

namespace Animal {
var haveMuscles = true; export function animalsHaveMuscles() {
return haveMuscles;
}
} namespace Animal {
export function doAnimalsHaveMuscles() {
return haveMuscles; // <-- error, haveMuscles is not visible here
}
}

因为haveMuscles并没有导出,只有animalsHaveMuscles函数共享了原始未合并的命名空间可以访问这个变量。 doAnimalsHaveMuscles函数虽是合并命名空间的一部分,但是访问不了未导出的成员。

命名空间与类和函数和枚举类型合并

命名空间可以与其它类型的声明进行合并。 只要命名空间的定义符合将要合并类型的定义。合并结果包含两者的声明类型。 Typescript使用这个功能去实现一些JavaScript里的设计模式。

首先,尝试将命名空间和类合并。 这让我们可以定义内部类。

class Album {
label: Album.AlbumLabel;
}
namespace Album {
export class AlbumLabel { }
}

合并规则与上面合并命名空间小节里讲的规则一致,我们必须导出AlbumLabel类,好让合并的类能访问。 合并结果是一个类并带有一个内部类。 你也可以使用命名空间为类增加一些静态属性。

除了内部类的模式,你在JavaScript里,创建一个函数稍后扩展它增加一些属性也是很常见的。 Typescript使用声明合并来达到这个目的并保证类型安全。

function buildLabel(name: string): string {
return buildLabel.prefix + name + buildLabel.suffix;
} namespace buildLabel {
export var suffix = "";
export var prefix = "Hello, ";
} alert(buildLabel("Sam Smith"));

相似的,命名空间可以用来扩展枚举型:

enum Color {
red = 1,
green = 2,
blue = 4
} namespace Color {
export function mixColor(colorName: string) {
if (colorName == "yellow") {
return Color.red + Color.green;
}
else if (colorName == "white") {
return Color.red + Color.green + Color.blue;
}
else if (colorName == "magenta") {
return Color.red + Color.blue;
}
else if (colorName == "cyan") {
return Color.green + Color.blue;
}
}
}

非法的合并

并不是所有的合并都被允许。 现在,类不能与类合并,变量与类型不能合并,接口与类不能合并。 想要模仿类的合并,请参考Mixins in TypeScript

转载:《TypeScript 中文入门教程》 11、声明合并的更多相关文章

  1. 转载:TypeScript 简介与《TypeScript 中文入门教程》

    简介 TypeScript是一种由微软开发的自由和开源的编程语言.它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程.安德斯·海尔斯伯格,C#的首席架构 ...

  2. 转载:《TypeScript 中文入门教程》

    缘由 事情是这样的,我想搜索 TypeScript 中文教程,结果在 https://www.baidu.com , https://cn.bing.com ,上都找不到官方的翻译,也没有一个像样的翻 ...

  3. 【转】TypeScript中文入门教程

    目录 虽然我是转载的,但看在Copy这么多文章也是很幸苦的好吧,我罗列一个目录. 转载:<TypeScript 中文入门教程> 17.注解 (2015-12-03 11:36) 转载:&l ...

  4. 《TypeScript 中文入门教程》

    转载:<TypeScript 中文入门教程> 17.注解 (2015-12-03 11:36) 转载:<TypeScript 中文入门教程> 16.Symbols (2015- ...

  5. 转载:《TypeScript 中文入门教程》 14、输入.d.ts文件

    版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 介绍 当使用外部JavaScript库或新的宿主API时,你需要一个声明文件(.d.t ...

  6. 转载:《TypeScript 中文入门教程》 7、模块

    版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 关于术语的一点说明: 请务必注意一点,TypeScript 1.5里术语名已经发生了变 ...

  7. 转载:《TypeScript 中文入门教程》 5、命名空间和模块

    版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 关于术语的一点说明: 请务必注意一点,TypeScript 1.5里术语名已经发生了变 ...

  8. 转载:《TypeScript 中文入门教程》 4、类

    版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 介绍 传统的JavaScript程序使用函数和基于原型的继承来创建可重用的组件,但这对 ...

  9. 转载:《TypeScript 中文入门教程》 17、注解

    版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 介绍 随着TypeScript和ES6里引入了类,现在在一些场景下我们会需要额外的特性 ...

随机推荐

  1. iOS创建安全的单例

    创建安全的单例 #import "Singleton.h" @implementation Singleton static Singleton* _instance = nil; ...

  2. Android开发学习之路-SnackBar使用心得

    SnackBar是DesignSupportLibrary中的一个重要的控件,用于在界面下面提示一些关键信息,跟Toast不同的地方是SnackBar允许用户向右滑动消除它,同时,也允许在SnackB ...

  3. StartUML的基础的使用,用例图,序列图

    转载地址  http://blog.csdn.NET/tianhai110 (下面参考了原博主的内容,也加入自己的内容,为了自己脑补,也方便其他看到的人脑补) 使用StartUML绘制用例图:     ...

  4. Distributed2:Linked Server Login 添加和删除

    一,通过 sys.sp_addlinkedsrvlogin 创建Linked Server的Login 当在local Server 上需要访问Linked Server时,Local Server ...

  5. 免费获取WP之类的开发者权限或免费使用Azure 2015-10-19

    上一次弄wp真机调试的时候,卡住了,这里讲一下怎么解决(http://www.cnblogs.com/dunitian/p/4870959.html) 进这个网址注册一下:https://www.dr ...

  6. SQL Server 维护计划实现数据库备份(策略实战)

    一.背景 之前写过一篇关于备份的文章:SQL Server 维护计划实现数据库备份,上面文章使用完整备份和差异备份基本上能解决数据库备份的问题,但是为了保障数据更加安全,我们需要再次完善我们的备份计划 ...

  7. Ruby之基本数据类型(三)

    前言 上一节我们介绍了常量以及变量的用法,这一节我们开始来介绍Ruby中的一些基本类型. 数值类型(Fixnum.Bignum.Float) Ruby的数值类型包括整数和浮点数.整数包括Fixnum和 ...

  8. Linux笔记之——Linux关机命令详解(转)

    原文连接:http://www.jb51.net/os/RedHat/1334.html 在linux下一些常用的关机/重启命令有shutdown.halt.reboot.及init,它们都可以达到重 ...

  9. 如何 判断 设备 是否 连接 上 了 wifi

    这里,我给出一个函数 public boolean sale_connect_check(WifiConfiguration wcg,Context context) { boolean judge_ ...

  10. 【jQuery小实例】---2自定义动画

    ---本系列文章所用使用js均可在本博客文件中找到 本节用jQuery完一个简易的动画效果,一个小驴跑跑的效果.和一个类似qq面板效果.大致也分为三步:添加jquery-1.8.3.js文件.这个是不 ...