转载:《TypeScript 中文入门教程》 11、声明合并
版权
文章转载自: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、声明合并的更多相关文章
- 转载:TypeScript 简介与《TypeScript 中文入门教程》
简介 TypeScript是一种由微软开发的自由和开源的编程语言.它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程.安德斯·海尔斯伯格,C#的首席架构 ...
- 转载:《TypeScript 中文入门教程》
缘由 事情是这样的,我想搜索 TypeScript 中文教程,结果在 https://www.baidu.com , https://cn.bing.com ,上都找不到官方的翻译,也没有一个像样的翻 ...
- 【转】TypeScript中文入门教程
目录 虽然我是转载的,但看在Copy这么多文章也是很幸苦的好吧,我罗列一个目录. 转载:<TypeScript 中文入门教程> 17.注解 (2015-12-03 11:36) 转载:&l ...
- 《TypeScript 中文入门教程》
转载:<TypeScript 中文入门教程> 17.注解 (2015-12-03 11:36) 转载:<TypeScript 中文入门教程> 16.Symbols (2015- ...
- 转载:《TypeScript 中文入门教程》 14、输入.d.ts文件
版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 介绍 当使用外部JavaScript库或新的宿主API时,你需要一个声明文件(.d.t ...
- 转载:《TypeScript 中文入门教程》 7、模块
版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 关于术语的一点说明: 请务必注意一点,TypeScript 1.5里术语名已经发生了变 ...
- 转载:《TypeScript 中文入门教程》 5、命名空间和模块
版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 关于术语的一点说明: 请务必注意一点,TypeScript 1.5里术语名已经发生了变 ...
- 转载:《TypeScript 中文入门教程》 4、类
版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 介绍 传统的JavaScript程序使用函数和基于原型的继承来创建可重用的组件,但这对 ...
- 转载:《TypeScript 中文入门教程》 17、注解
版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 介绍 随着TypeScript和ES6里引入了类,现在在一些场景下我们会需要额外的特性 ...
随机推荐
- Ubuntu系统字体安装
用惯了Windows,刚转到Ubuntu时总感觉字体显示没那么亲切,尤其是中文字体,在网页上显示特别怪.有些软件对中文字体的支持也不好,WebStorm中的Git logs中文也显示乱码.把系统语言设 ...
- Java ServletContextListener用法
ServletContext 被 Servlet 程序用来与 Web 容器通信.例如写日志,转发请求.每一个 Web 应用程序含有一个Context,被Web应用内的各个程序共享.因为Context可 ...
- iOS中通讯录的开发
通讯录开发主要是获取用户手机中的联系人,进而可以在应用中添加好友 一 .如何访问通讯录 (1)在iOS9之前,有两个框架可以访问用户的通讯录 AddressBookUI.framework: 提供了联 ...
- 解决升级Win 10 IP 10122后无法调试UAP应用的方法
可能各位也像老周一样,第一时间升级了Build 10122,但不知道大家有没有发现,当你升级后,写一个UAP应用,要调试运行时,就会出错,错误如下: DEP0730 : 注册应用程序失败,因为目标计算 ...
- Visulalization Voronoi in OpenSceneGraph
Visulalization Voronoi in OpenSceneGraph eryar@163.com Abstract. In mathematics a Voronoi diagram is ...
- Windows phone重写返回键
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e) {//需要设置这个属性 e.Cancel ...
- 校验码(海明校验,CRC冗余校验,奇偶校验)
循环冗余校验码 CRC码利用生成多项式为k个数据位产生r个校验位进行编码,其编码长度为n=k+r所以又称 (n,k)码. CRC码广泛应用于数据通信领域和磁介质存储系统中. CRC理论非常复杂,一般书 ...
- iOS开发之版本控制(SVN)
版本控制对于团队合作显得尤为重要,那么如何在iOS开发中进行版本控制呢?在今天的博客中将会介绍如何在MAC下配置SVN服务器,如何导入我们的工程,如何在Xcode中进行工程的checkOut和Comm ...
- Ubuntu杂记——Ubuntu下安装VMware
转战Ubuntu,不知道能坚持多久,但是自己还是要努力把转战过程中的学习到的给记录下来.这次就来记录一下,Ubuntu下如何安装VMware. 就我所知,Linux下有VirtualBox和VMwar ...
- C语言 第一章 C语言简介
一.C语言介绍 C是一种通用的编程语言,广泛用于系统软件与应用软件的开发.于1969年至1973年间,为了移植与开发UNIX操作系统,由丹尼斯·里奇与肯·汤普逊,以B语言为基础,在贝尔实验室设计.开发 ...