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. Iptables防火墙规则使用梳理

    iptables是组成Linux平台下的包过滤防火墙,与大多数的Linux软件一样,这个包过滤防火墙是免费的,它可以代替昂贵的商业防火墙解决方案,完成封包过滤.封包重定向和网络地址转换(NAT)等功能 ...

  2. Mysql双主热备+LVS+Keepalived高可用操作记录

    MySQL复制能够保证数据的冗余的同时可以做读写分离来分担系统压力,如果是主主复制还可以很好的避免主节点的单点故障.然而MySQL主主复制存在一些问题无法满足我们的实际需要:未提供统一访问入口来实现负 ...

  3. linux书籍

    <鸟哥私房菜-基础版> <实战LINUX_SHELL编程与服务器管理> <LINUX命令行与SHELL脚本编程大全第2版].布卢姆.扫描版> <Linux初学 ...

  4. 作业20171116 beta2及beta发布 成绩

    申诉 对成绩有疑问或不同意见的同学,请在群里[@杨贵福]. 申诉时间截止2017年12月13日 17:00. 成绩 scrum01 scrum02 scrum03 scrum04 scrum05 sc ...

  5. SCRUM 12.23

    距离第二轮迭结束只有几天了. 我们全体组员现在的工作方向都在应用测试上. 明天的任务分配如下 成员 已完成任务 新任务 彭林江 落实API 自动爬虫测试 王卓 提升爬虫程序性能 正确性测试 郝倩 提升 ...

  6. beta阶段测试基本概况报告

    文件地址 测试基本信息                                                                                Bitmap 测试 ...

  7. JAVA面对对象(五)——接口

    接口由全局常量和公共的抽象方法组成,接口的定义格式: interface 接口名称{ 全局常量; 抽象方法; } 接口中的抽象方法必须定义为public访问权限,在接口中如果不写也默认是public访 ...

  8. Jfrog Artifactory 创建docker 镜像仓库以及 push 镜像到 该仓库.

    1. 安装aitifactory 以及 启动 使用30天有效期激活 不在阐述. 2. 登录artifactory username:admin password:password 3. 创建 仓库 在 ...

  9. python拉格朗日插值

    #拉格朗日插值代码 import pandas as pd #导入数据分析库Pandas from scipy.interpolate import lagrange #导入拉格朗日插值函数 inpu ...

  10. WINFORM 多条件动态查询 通用代码的设计与实现

    经常碰到多条件联合查询的问题,以前的习惯认为很简单总会从头开始设计布局代码,往往一个查询面要费上老半天的功夫,而效果也不咋地.     前段时间做了个相对通用的多条件动态查询面,复用起来还是挺方便的, ...