版权

文章转载自: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. ASP.NET MVC 5 - 给电影表和模型添加新字段

    在本节中,您将使用Entity Framework Code First来实现模型类上的操作.从而使得这些操作和变更,可以应用到数据库中. 默认情况下,就像您在之前的教程中所作的那样,使用 Entit ...

  2. 学习Cassandra的开源电子书(中英文版)

    学习Cassandra的开源电子书(中英文版)发布啦:http://teddymaef.github.io/learncassandra/ 之前发布了英文版,现在包含中文版了. 学习Cassandra ...

  3. 通过圆形载入View了解自定义View

    这是自定义View的第一篇文章,通过制作简单的自定义View来了解自定义View的流程. 自定义View是Android学习和开发中必不可少的一部分.通过自定义View我们可以制作丰富绚丽的控件,自定 ...

  4. Java学习笔记(04)

    Java学习笔记(04) 如有不对或不足的地方,请给出建议,谢谢! 一.对象 面向对象的核心:找合适的对象做合适的事情 面向对象的编程思想:尽可能的用计算机语言来描述现实生活中的事物 面向对象:侧重于 ...

  5. JS数字计算精度误差的解决方法

    本篇文章主要是对javascript避免数字计算精度误差的方法进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助. 如果我问你 0.1 + 0.2 等于几?你可能会送我一个白眼,0.1 + 0. ...

  6. lua解析脚本过程中的关键数据结构介绍

    在这一篇文章中我先来介绍一下lua解析一个脚本文件时要用到的一些关键的数据结构,为将来的一系列代码分析打下一个良好的基础.在整个过程中,比较重要的几个源码文件分别是:llex.h,lparse.h.l ...

  7. ASP.NET MVC5 网站开发实践(二) Member区域 - 修改及删除文章

    上次做了显示文章列表,再实现修改和删除文章这部分内容就结束了,这次内容比较简单,由于做过了添加文章,修改文章非常类似,就是多了一个TryUpdateModel部分更新模型数据.   目录: ASP.N ...

  8. Hibernate注解

    前言: 最近正在学习Hibernate通过注解(annotation)来管理映射关系,以前都是通过XML映射文件.下面拿个小例子说一下. 数据库物理模型: 数据库的描述: 一篇博客随笔可以分到不同的类 ...

  9. DOM-Text类型、Comment类型、CDATASection类型、DocumentType类型、DocumentFragment类型、Attr类型

    Text类型 文本节点由Text类型表示,包含的是可以照字面解释的纯文本内容.Text节点具有以下特征: nodeType的值为3 nodeName的值为"text" nodeVa ...

  10. The network bridge on device VMnet0 is not running

    The network bridge on device VMnet0 is not running. The virtual machine will not be able to communic ...