Interfaces

作为TypeScript中的核心特色之一,能够让类型检查帮助我们知道一个对象应该有什么,相比我们在编写JavaScript的时候经常遇到函数需要传递参数,可能在编写的时候知道这个对象能够提供哪些值,但是以后维护的时候负责看这段代码的人都无法确认这个对象还有其他的哪些值,就需要翻阅源码看看调用这个函数的代码。

第一个接口

在开始正题之前我们先来一个简单的例子。

--TypeScript

 function printLabel(labelObject: { label: string }) {
console.log(labelObject.label);
} var myobj = { size: 10, label: "Size 10 Object" };
printLabel(myobj);

--JavaScript

function printLabel(labelObject) {
console.log(labelObject.label);
} var myobj = { size: 10, label: "Size 10 Object" };
printLabel(myobj);

类型检查会在我们调用printLabel的时候检查传进去的参数,确保该参数中存在一个名字为label并且类型为string的属性,当然我们可以看到这个参数的值远远比我们函数要求的多,但这并不会造成影响,通过最终的源码我们也可以看到最终生成的js代码并没有比原来多出多少,但是却能够为我们提供强大的类型检查。

下面我们可以引入正题了,我们将使用接口的方式实现上面的例子。

--TypeScript

 interface LabelledValue {
label: string
} function printLabel(labelObject: LabelledValue) {
console.log(labelObject.label);
} var myobj = { size: 10, label: "Size 10 Object" };
printLabel(myobj);

--JavaScript

同上

这里我们看到如果利用接口能够更便于管理,更主要的是接口中除了可以定义属性也可以定义函数等,对于中大型项目,特别是前后端分离的网站来说对于以后的维护和迭代能顾节省时间成本并提高质量。

可选属性

但是由于历史原因,TypeScript并不能孤立存在,还是需要兼容其他库,那么就导致我们的接口还要考虑另一种情况就是可选值,比如下面这个例子。

--TypeScript

 interface SquareConfig {
color?: string;
width?: number;
} function createSquare(config: SquareConfig): { color: string; area: number } {
var newsquare = { color: "white", area: 100 };
if (config.color) {
newsquare.color = config.color;
}
if (config.width) {
newsquare.area = config.width * config.width;
}
return newsquare;
} var mySquare = createSquare({ color: "black" });

--JavaScript

 function createSquare(config) {
var newsquare = { color: "white", area: 100 };
if (config.color) {
newsquare.color = config.color;
}
if (config.width) {
newsquare.area = config.width * config.width;
}
return newsquare;
} var mySquare = createSquare({ color: "black" });

通过接口我们知道可选属性就是在属性名称的后面加上问号就可以了,但是开发的时候要注意就是要通过if判断下该值是否存在。

函数类型

玩转了属性,下面我们开始在接口中放入函数,下面我们先放一个函数。

--TypeScript

 interface SearchFunc {
(source: string, substring: string): boolean;
} var mySearch: SearchFunc;
mySearch = function (source: string, substring: string) {
var result = source.search(substring);
if (result == -1) {
return false;
} else {
return true;
}
};

--JavaScript

var mySearch;
mySearch = function (source, substring) {
var result = source.search(substring);
if (result == -1) {
return false;
} else {
return true;
}
};

大家肯定会很奇怪,下面为什么定义了这个接口的变量但是赋的确是一个函数,如果大家有C#和java语言的基础会发现SearchFunc中的函数是没有函数名的,所以mySearch的类型就是一个函数,只是会进行类型检查,你是不能赋其他函数签名不一样的函数给他的。

数组类型

接口除了可以描述函数类型也可以描述数组类型,数组类型拥有一个“index”类型,是用来索引数组的,利用这个我们就可以实现除了数组以外还能够实现字典类型。

--TypeScript

 interface StringArray {
[index: number]: string;
} var myArray: StringArray;
myArray = ["Bob", "Fred"];

--JavaScript

 var myArray;
myArray = ["Bob", "Fred"];

Index类型能够支持两种类型:string和number,所以我们能够实现字典类型,比如下面这种类型。

--TypeScript

 interface StringArray {
[index: string]: string;
} var myArray: StringArray;
myArray = {
"dede": "dede",
"ete":"dede"
};

--JavaScript

 var myArray;
myArray = {
"dede": "dede",
"ete": "dede"
};

类类型

像C#和Java语言中一样,接口最基础的作用就是让类去实现接口,所以这也是TypeScript语言的特点之一。比如下面的例子我们将实现一个带有一个属性的接口。

--TypeScript

 interface ClockInterface {
currentTime: Date
} class Clock implements ClockInterface {
currentTime: Date;
constructor(h: number, m: number) { }
}

--JavaScript

 var Clock = (function () {
function Clock(h, m) {
}
return Clock;
})();

这里我们可以看到最终的JS中并没有将currentTime作为变量加入到this中,因为在这个类中我们并没有使用到这个值,所以这个变量只会在我们正式的使用的时候添加到这个类中,如果不用这个类就等同于没有这个变量。

上面我们仅仅只是在接口中写了一个属性,下面我们在接口中增加一个方法。

--TypeScript

 interface ClockInterface {
currentTime: Date;
setTime(d: Date);
} class Clock implements ClockInterface {
currentTime: Date;
setTime(d: Date) {
this.currentTime = d;
}
constructor(h: number, m: number) { }
}

--JavaScript

 var Clock = (function () {
function Clock(h, m) {
}
Clock.prototype.setTime = function (d) {
this.currentTime = d;
};
return Clock;
})();

静态类和实例类的区别

当我们使用类和接口,需要知道类是存在静态和实例的,这也就意味着如果你的接口如果存在构造方法并且需要一个类去实现,那么你将会看到错误信息,比如下面这段。

--TypeScript

 interface ClockInterface {
new (hour: number, minute: number);
} class Clock implements ClockInterface {
currentTime: Date;
constructor(h: number, m: number) { }
}

这是因为当一个类实现一个接口的时候只有实例部分是被允许的,而构造方法恰恰属于静态,并不包含在内。

当然含有构造方法的接口是有其用途的,比如下面这样的用法。

--TypeScript

 interface ClockInterface {
new (hour: number, minute: number);
} class Clock {
currentTime: Date;
constructor(h: number, m: number) { }
} var cs: ClockInterface = Clock;
var newClock = new cs(2, 3);

--JavaScript

 var Clock = (function () {
function Clock(h, m) {
}
return Clock;
})(); var cs = Clock;
var newClock = new cs(2, 3);

扩展接口

这个特性跟类可以继承其他类一样,接口也可以扩展其他的接口,这将会导致被继承的接口中的所有的内容都会被复制到另一个接口中。下面我们来看一个简单的例子。

--TypeScript

 interface Shape {
color: string;
} interface Square extends Shape {
sideLength: number;
} var square = <Square>{};
square.color = "blue";
square.sideLength = 10;

--JavaScript

 var square = {};
square.color = "blue";
square.sideLength = 10;

一个接口不仅仅只能扩展一个接口,是可以扩展多个接口的。比如下面这样。

--TypeScript

 interface Shape {
color: string;
} interface PenStroke {
penWidth: number;
} interface Square extends Shape, PenStroke {
sideLength: number;
} var square = <Square>{};
square.color = "blue";
square.sideLength = 10;
square.penWidth = 5.0;

--JavaScript

 var square = {};
square.color = "blue";
square.sideLength = 10;
square.penWidth = 5.0;

混合类型

我们再次之前提到过,接口可以描述很多真实世界中JavaScript的类型,因为JavaScript的动态和天生的灵活性,你或许会遇到一些需要多种复合的类型。

比如下面的实例,这个对象将扮演着函数和一个对象。

--TypeScript

 interface Counter {
(start: number): string;
interval: number;
reset(): void;
} var c: Counter;
c(10);
c.reset();
c.interval = 5.0;

--JavaScript

 var c;
c(10);
c.reset();
c.interval = 5.0;

对于需要使用第三方JavaScript库的情况下,我们就会需要使用到上面介绍的知识。当然现在很多常用的JavaScript库都已经存在了,我们可以通过nuget获取到。

TypeScript之接口类型的更多相关文章

  1. TypeScript学习笔记之接口类型

    TypeScript的接口,个人理解就是一种约束,包括各种类型的契约或者代码定义上的契约.当然,和java中的用法基本一致,接口可以被继承也可以被实现. 定义一个简单的interface interf ...

  2. TypeScript Type Compatibility(类型兼容)

    TypeScript中的类型兼容是基于结构归类的.在普通分类的相比之下,结构归类是一种纯粹用于将其成员的类型进行关联的方法.思考下面的代码: interface Named { name: strin ...

  3. TypeScript 之 基础类型、高级类型

    基础类型:https://m.runoob.com/manual/gitbook/TypeScript/_book/doc/handbook/Basic%20Types.html 高级类型:https ...

  4. TypeScript完全解读(26课时)_11.TypeScript完全解读-类型推论和兼容性

    11.TypeScript完全解读-类型推论和兼容性 在一些时候省略指令,ts会帮我们推断出省略的类型的地方适合的类型,通过学习ts的类型推论了解ts的推论规则 类型兼容性就是为了适应js灵活的特点, ...

  5. TypeScript入门五:TypeScript的接口

    TypeScript接口的基本使用 TypeScript函数类型接口 TypeScript可索引类型接口 TypeScript类类型接口 TypeScript接口与继承 一.TypeScript接口的 ...

  6. 无法将类型为“Microsoft.Office.Interop.Word.ApplicationClass”的 COM 对象强制转换为接口类型“Microsoft.Office.Interop.Word._Application”。

    无法将类型为“Microsoft.Office.Interop.Word.ApplicationClass”的 COM 对象强制转换为接口类型“Microsoft.Office.Interop.Wor ...

  7. TypeScript Type Innference(类型推断)

    在这一节,我们将介绍TypeScript中的类型推断.我们将会讨论类型推断需要在何处用到以及如何推断. 基础 在TypeScript中,在几个没有明确指定类型注释的地方将会使用类型推断来提供类型信息. ...

  8. (转)无法将类型为“Microsoft.Office.Interop.Word.ApplicationClass”的 COM 对象强制转换为接口类型“Microsoft.Office.Interop.Word._Application”。此操作失败的原因是对 IID 为“{00020970-

    HRESULT:0x80030002 无法将类型为“Microsoft.Office.Interop.Word.ApplicationClass”的 COM 对象强制转换为接口类型“Microsoft ...

  9. 无法将类型为 excel.applicationclass 的 com 强制转换为接口类型 的解决方法。

    今天碰到客户的电脑在导出EXCEL的时候提示,无法将类型为 excel.applicationclass 的 com 强制转换为接口类型 excel._application 的问题 最后用下面的方法 ...

随机推荐

  1. 记一次PHP7+opcache+zmq出现SIGSEGV 问题的查找(一次不成功的bug查找)

    Title:  记一次PHP7+opcache+zmq出现SEGSEGV问题的查找(一次不成功的bug查找) bug来历自述:线上代码PHP环境是5.2,为了提升性能(逼格),于是升级为PHP7并使用 ...

  2. MongoDB 知识要点一览

    1.启动mongoDb数据库: 进入mongoDB的安装目录,执行如下命令 C:\Program Files\MongoDB\Server\3.0\bin>mongod.exe --dbpath ...

  3. ZOJ 3705 Applications 模拟

    #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include< ...

  4. 新版Xcode无法新建iOS空项目解决方案

    --感谢同学分享-- 操作说明: 拷贝Empty Application.xctemplate文件夹至   /Contents/Developer/Platforms/iPhoneOS.platfor ...

  5. CSS布局技巧 -- sticky属性

    在一些很长的表格中,往往需要使用表头悬浮的设计以方便用户使用,例如H5电商页面通过下滑展示大量商品列表时,顶部的导航栏需要在离开屏幕时,需要固定在屏幕顶部以方便用户筛选类别.这种效果一直以来需要通过J ...

  6. (Python )格式化输出、文件操作、json

    本节学习Python的格式化输出,文件操作以及json的简单用法 1.格式化输出 将非字符串类型转换成字符串,可以使用函数:str() 或者repr() ,(这两个函数的区别目前我还没搞懂,求解答) ...

  7. python第一天基础1-1

    win下是没有多进程的 windows:1.下载安装包 https://www.python.org/downloads/2.安装 默认安装路径:C:\python273.配置环境变量 [右键计算机] ...

  8. 在SqlServer查询分析器里 访问远程数据库 进行数据查询更新等操作(openrowset)

    启用Ad Hoc Distributed Queries: exec sp_configure 'show advanced options',1 reconfigure exec sp_config ...

  9. zTree+EasyUi做权限遇到的小问题

    最近需要做一个zTree+EasyUi的权限管理系统,以前有过接触,在做这一块时,用到了ztree,树来加载咱们的菜单栏,后台获取登录用户信息的权限列表,转换成json对象来加载到咱们的树当中,代码如 ...

  10. 高速PCB之EMC设计47则

    高速PCB之EMC设计47则 差模电流和共模电流 辐射产生 电流导致辐射,而非电压,静态电荷产生静电场,恒定电流产生磁场,时变电流既产生电场又产生磁场.任何电路中存在共模电流和差模电流,差模信号携带数 ...