typescript的核心原则之一就是对所具有的shape类型检查结构性子类型化

One of the core principles of typescript is to check structural subtyping of shape types

在typescript中,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约

In typescript, the function of an interface is to name these types and define contracts

for your code or third-party code.

function printLable(labelledObj:{label:string}){
console.log(labelledObj.label);
}
let myObj={size:10,label:"Size 10 Object"};
printLable(myObj);

我们分析代码可以知道,一个对象有label对象,它的值类型是string类型

If we analyze the code, we can see that an object has a label object whose value type is string type.

使用接口重写上面的例子

Rewrite the above example using an interface

interface LabelledValue{
label:string;
}
function printLable(labelledObj:LabelledValue){
console.log(labelledObj.label);
}
let myObj={Size:10,label:"Size 10 Object"};
printLable(myObj);
//类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型也是对的就可以
/*The type checker does not check the order of attributes, as long as the corresponding
attributes exist and the type is correct.*/

可选属性。option bags 模式时很常用。接口里的属性不会都是必选的。有些只是在某些条件下存在,或者根本不存在

Optional properties. Option bags mode is often used. Attributes in interfaces are not always required.

Some exist only under certain conditions, or nonexistent at all.

即给函数传入的参数对象中只有部分属性赋值了。

That is to say, only part of the parameter object passed in by the function is assigned to its attributes.

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

只读属性

Read-only attribute

interface Point{
readonly x:number;
readonly y:number;
}

通过赋值一个对象字面量来构造一个Point

Constructing a Point by assigning an object literal

let p1:Point={x:20,y:20};
p1.x=5;//error

typescript具有readonlyArray类型,它与Array相似,只是把所有可变方法去掉了

Typeescript has the readonlyArray < T > type, which is similar to Array < T > except that all the variable methods are removed.

因此可以确保数组创建后再也不能被修改

So you can make sure that arrays can never be modified after they are created.

let a:number[]=[1,2,3,4];
let ro:ReadonlyArray<number>=a;
ro[0]=12;//error
ro.push(5);//error
ro.length=100;//error
a=ro;//error

用类型断言重写

Rewrite with type assertions

a=ro as number[];

readonly vs const

最早判断该用readonly还是const的方法是要看把它作为变量使用还是作为一个属性

The earliest way to determine whether to use readonly or const is to use it as a variable or as an attribute

作为变量使用的话用const,若作为属性使用则用readonly

Use const as a variable and read only as an attribute

额外的属性检查

Additional property checking

interface SquareConfig{
color?:string;
width?:number;
}
function createSquare(config:SquareConfig):{color:string;area:number}{
}

对象字面量会被特殊对待而且会经过 额外属性检查,当将它们赋值给变量或作为参数传递的时候。

Object literals are treated specially and are checked for additional attributes when they are assigned to variables or passed as parameters.

如果一个对象字面量存在任何“目标类型”不包含的属性时,你会得到一个错误。

If an object literal has any attributes that the "target type" does not contain, you get an error.

let mySquare=createSquare({colour:"red",width:100});

绕开这些检查非常简单。 最简便的方法是使用类型断言:

It's very simple to bypass these checks. The easiest way is to use type assertions:

let mySquare=createSquare({width:100,opacity:0.5}as SquareConfig);

最佳的方式是能够添加一个字符串索引签名,前提是你能够确定这个对象可能具有某些做为特殊用途使用的额外属性

The best way to do this is to be able to add a string indexed signature, provided you can determine that

the object may have some additional properties for special purposes.

interface SquareConfig{
color?:string;
width?:number;
[proName:string]:any;//任意数量的属性
}

它就是将这个对象赋值给一个另一个变量: 因为squareOptions不会经过额外属性检查,所以编译器不会报错。

It assigns this object to another variable: because squareOptions does not undergo additional property checks,

the compiler does not report errors.

let squareOptions = { colour: "red", width: 100 };
let mySquare = createSquare(squareOptions);

函数类型

Function Type

接口能够描述JavaScript中对象拥有的各种各样的外形。

除了描述带有属性的普通对象外,接口也可以描述函数类型。

Interfaces can describe the various shapes of objects in JavaScript.

In addition to describing common objects with attributes, interfaces can also describe function types.

为了使用接口表示函数类型,我们需要给接口定义一个调用签名。

它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型。

In order to use interfaces to represent function types, we need to define a call signature for

the interface. It's like a function definition with only parameter lists and return value types.

Each parameter in the parameter list needs a name and type.

interface SearchFunc{
(source:string,subString:string):boolean;
}

这样定义后,我们像使用其他接口意义使用这个函数型的接口

如何创建一个函数类型的变量并将一个同类型函数赋值给这个变量

With this definition, we use this functional interface in the sense of other interfaces.

How to create a variable of function type and assign a function of the same type to the variable

let mySearch:SearchFunc;
mySearch=function(source:string,subString:string){
let result=source.search(subString);
if(result==-1){
return false;
}else{
return true;
}
}

对于函数类型的类型检查来说,函数的参数名不需要与接口里定义的名字相匹配

For type checking of function types, the parameter name of a function

does not need to match the name defined in the interface.

let mySearch:SearchFunc;
mySearch=function(src:string,sub:string):boolean{
let result=src.search(sub);
if(result==-1){
return false;
}else {
return true;
}
}
let mySearch:SearchFunc;
mySearch=function(src,sub){
let result=src.search(sub);
if(result==-1){
return false;
}else{
return true;
}
}

可索引的类型

Indexable types

interface StringArray{
[index:number]:string;
// 这个索引签名表示了当用 number去索引StringArray时会得到string类型的返回值。
//This index signature represents the return value of string type when StringArray is indexed with number.
}
let myArray:StringArray;
myArray=["bob","tine"];
let myStr:string=myArray[0]; class Animal{
name:string;
}
class Dog extends Animal{
breed:string;
}
interface NotOkay{
[x:number]:Animal;
[x:string]:Dog;
}

字符串索引签名能够很好的描述dictionary模式,并且它们也会确保所有属性与其返回值类型相匹配。

因为字符串索引声明了 obj.property和obj["property"]两种形式都可以。

String indexed signatures describe dictionary patterns well, and they also ensure that all attributes

match their return value types. Because the string index declares

that both obj. property and obj ["property"] can be used.

interface NumberDictionary{
[index:string]:number;
length:number;
name:string;
//name的类型不是索引类型的子类型
//The type of name is not a subtype of the index type
}

将索引类型设置为只读,这样就防止了给索引赋值

Setting the index type to read-only prevents index assignment

interface ReadonlyStringArray{
readonly [index:number]:string;
}
let myArray:ReadonlyStringArray=["Alice","Bob"];
myArray[2]="Mallory";//error

类类型

Class type

TypeScript也能够用它来明确的强制一个类去符合某种契约。

TypeScript can also be used to explicitly force a class to conform to a contract.

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

在接口中描述一个方法,在类里实现它,如同下面的setTime方法一样:

Describe a method in the interface and implement it in the class,

just like the setTime method below:

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

接口描述了类的公共部分,而不是公共和私有两部分。 它不会帮你检查类是否具有某些私有成员。

Interfaces describe the public part of a class, not the public and private parts.

It doesn't help you check whether a class has some private members.

类静态部分与实例部分的区别

The Difference between Class Static Part and Example Part

ColockConstuctor为构造函数所用

ColockConstuctor for constructors

ClockInterface为实例方法所用

ClockInterface for instance methods

interface ClockConstuctor{
new(hour:number,minute:number):ClockInterface;
}
interface ClockInterface{
tick();
}
function createClock(ctor:ClockConstuctor,hour:number,minute:number):
ClockInterface{
return new ctor(hour,minute);
}
class DigitalClock implements ClockInterface{
constructor(h:number,m:number){}
tick(){
console.log("beep beep");
}
}
class AnalogClock implements ClockInterface{
constructor(h:number,m:number){}
tick(){
console.log("tick tock")
}
}
let digital=createClock(DigitalClock,12,17);
let analog=createClock(AnalogClock,7,32);

扩展接口

Extended interface

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

一个接口可以继承多个接口,创建出多个接口的合成接口

An interface can inherit multiple interfaces and create a composite interface of multiple interfaces.

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

混合类型

Mixed type

一个对象可以同时作为函数和对象使用,并带有额外的属性

An object can be used as both a function and an object with additional attributes

interface Counter{
(start:number):string;
interval:number;
reset():void;
}
function getCounter():Counter{
let counter=<Counter>function(start:number){};
counter.interval=123;
counter.reset=function(){};
return counter;
}
let c=getCounter();
c(10);
c.reset();
c.interval=5.0;

接口继承类

Interface inheritance class

class Control {
private state: any;
} interface SelectableControl extends Control {
select(): void;
} class Button extends Control {
select() { }
}
class TextBox extends Control {
select() { }
}
class Image {
select() { }
}
class Location {
select() { }
}

typescript接口(学习笔记非干货)的更多相关文章

  1. typescript泛型(学习笔记非干货)

    软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性. 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型, 这在创建大型系统时为你提供了十分灵活的功能. In softwa ...

  2. typescript类(学习笔记非干货)

    我们声明一个 Greeter类.这个类有3个成员:一个叫做greeting的属性,一个构造函数和一个greet方法. We declare a Greeter class. This class ha ...

  3. typescript基础类型(学习笔记非干货)

    布尔值 Boolean let isDone:boolean=false; 数字 Number let decLiteral:number=6; let hexLiteral:number=0xf00 ...

  4. typescript枚举,类型推论,类型兼容性,高级类型,Symbols(学习笔记非干货)

    枚举部分 Enumeration part 使用枚举我们可以定义一些有名字的数字常量. 枚举通过 enum关键字来定义. Using enumerations, we can define some ...

  5. typescript变量声明(学习笔记非干货)

    var a=10; function f(){ var message="hello,world"; return message; } function f(){ a=10; r ...

  6. mongoDB 学习笔记纯干货(mongoose、增删改查、聚合、索引、连接、备份与恢复、监控等等)

    最后更新时间:2017-07-13 11:10:49 原始文章链接:http://www.lovebxm.com/2017/07/13/mongodb_primer/ MongoDB - 简介 官网: ...

  7. typescript handbook 学习笔记4

    概述 这是我学习typescript的笔记.写这个笔记的原因主要有2个,一个是熟悉相关的写法:另一个是理清其中一些晦涩的东西.供以后开发时参考,相信对其他人也有用. 学习typescript建议直接看 ...

  8. typescript handbook 学习笔记3

    概述 这是我学习typescript的笔记.写这个笔记的原因主要有2个,一个是熟悉相关的写法:另一个是理清其中一些晦涩的东西.供以后开发时参考,相信对其他人也有用. 学习typescript建议直接看 ...

  9. typescript handbook 学习笔记2

    概述 这是我学习typescript的笔记.写这个笔记的原因主要有2个,一个是熟悉相关的写法:另一个是理清其中一些晦涩的东西.供以后开发时参考,相信对其他人也有用. 学习typescript建议直接看 ...

随机推荐

  1. 微信小程序开发工具 ubuntu linux版本

    安装 http://blog.csdn.net/zhangyingguangails/article/details/72517182 sudo apt install wine sudo git c ...

  2. Docker容器学习梳理 - 私有仓库Registry使用

    但有时候使用Docker Hub这样的公共仓库可能不方便,这种情况下用户可以使用registry创建一个本地仓库供私人使用,这点跟Maven的管理类似.使用私有仓库有许多优点: 1)节省网络带宽,针对 ...

  3. Python-集合-17

    ''' 集合:可变的数据类型,他里面的元素必须是不可变的数据类型,无序,不重复. {} ''' set1 = set({1,2,3}) # set2 = {1,2,3,[2,3],{'name':'a ...

  4. M2事后总结

    照片     设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? "北航"Clubs旨在于解决北航校内社团管理与学生参与社团活动的困难的 ...

  5. Linux 第八周实验 进程的切换和系统的一般执行过程

    姬梦馨 原创作品 <Linux内核分析>MOOC课程:http://mooc.study.163.com/course/USTC-1000029000 第八讲 进程的切换和系统的一般执行过 ...

  6. Opentsdb分布式安装

    Opentsdb分布式安装 --李琦 1.下载文件上传到虚拟机 -rw-r--r--.  1 root   root  76793860 Apr 27 10:56 opentsdb-2.2.0.tar ...

  7. personal project

    words count program 统计文本文件的字符数,单词数和行数. 实现一个统计程序,他能正确的统计程序文件中的字符数,单词数和行数. 源码链接 https://github.com/sup ...

  8. SE Springer小组之《Spring音乐播放器》需求分析说明书二

    2.1 目标 Spring音乐播放器软件为课程<软件工程>所开发的课程作业,主要意图是为访问计算机中的mp3格式的音频文件,并使其能够完成访问,读取,添加,保存,播放,切换音频文件等功能. ...

  9. 转帖--计算机网络基础知识大总汇 https://www.jianshu.com/p/674fb7ec1e2c?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

    计算机网络基础知识大总汇 龙猫小爷 关注 2016.09.14 23:01* 字数 12761 阅读 30639评论 35喜欢 720 一.什么是TCP/IP 网络和协议 1.     TCP/IP是 ...

  10. delphi7调用数据库连接属性

    背景:连接数据库用ADOQuery控件,但是程序一旦编译完成,如果想更改数据库连接设置还得重新修改ADOQuery的属性重新编译 如果可以在程序中可以随时设置ADOQuery的属性则会方便很多. 实现 ...