TypeScript学习笔记之接口类型

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

定义一个简单的interface

interface LabelledValue {
  label: string;
}

function printLabel(labelledValue: LabelledValue) {
  console.log(labelledValue.label);
}

let myLabel: LabelledValue = {label: 'this is my label'}
printLabel(myLabel)   // this is my label

注意:
    1、可选属性:label?: string;
    2、只读属性:readonly label: string;(只允许创建的时候修改一次)
    
readonly和const:变量声明用const,属性声明用readonly

看一个readonly的例子:

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

let p1: Point = {x: 121, y: 78}
console.log(p1);    // {x: 121, y: 78}

p1.x = 22   // wrong! 

注意:
    如果是只读型数组,请使用ReadonlyArray

额外属性检查

任意数量属性

interface SquareConfig {
  color?: string;
  width?: number;
  [propName: string]: any;    // 代表任意属性,其中key类型为string,value类型为any任意
}

函数类型接口

接口可以描述js对象中拥有的各种外形。比如如下可以描述js对象具有函数类型:

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

let mySearch: SearchFunc;
mySearch = function(src, sub) {     // ts会自动识别参数类型,参数名可以不一致
    let result = src.search(sub);
    return result > -1;
}

其中,source、subString均为string型入参,boolean类型为出参。

可索引的类型

接口描述这种类型,比较有意思,可索引的类型包含两种,一种是对象,一种的数组。可以在接口中描述索引的类型,以及索引值的类型,如下:

interface StringArray {
  [index: number]: string;
}

let z1: StringArray = {1: "awdawd"}
let z2: StringArray = ['admin']
console.log(z1, z2);    // { '1': 'awdawd' } [ 'admin' ]

如上接口,可以被数组实现,也可以被对象实现。索引签名除了number还要string,可以同时使用两种类型的索引。但是要注意:数字类型索引的索引值一定要是字符串索引类型索引值的子类型。举个例子:

class Animal {
  name: string;
}
class Dog extends Animal {
  breed: string;
}

// 错误:使用'string'索引,有时会得到Animal!
interface NotOkay {
  [x: number]: Animal;
  [x: string]: Dog;
}

说明,按照意思是number索引类型是Animal,string索引类型是Dog,Animal必须是Dog的子类型,但是实际恰恰相反——Dog是Animal类型的子类型,所以这里会报错。因为当使用number作索引时,js会将它转换为string,然后再去索引。所以必须保证number索引是string索引的子类型,否则会造成索引值混乱。

使用索引签名实现ReadonlyArray效果:

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

实现一个接口

在java里面,接口生来就是被实现的,就好像抽象对象生来就是要被继承一样。

interface ClockInterface {    // 定义接口,包含属性currentTime,所有该接口的实现必须包含该字段
  currentTime: Date;
}

class Clock implements ClockInterface{
  currentTime: Date;    // 该字段必须包含
  constructor(h: number, m: number){};
}

同样地,在接口里面可以再加函数约束,所有实现必须重写该函数:

interface ClockInterface {    // 定义接口,包含属性currentTime,所有该接口的实现必须包含该字段
  currentTime: Date;
  setTime(d: Date);
}

class Clock implements ClockInterface{
  currentTime: Date;    // 该字段必须包含
  setTime(d: Date) {
    this.currentTime = d;
  }
  constructor(h: number, m: number){};
}

继承一个接口

接口和类相似,彼此之间是可以相互继承的,使用关键字extend实现:

interface Shape {
    color: string;
}

interface Square extends Shape {
    sideLength: number;
}

let square = <Square>{};        // 断言,同:{} as Square
square.color = "blue";
square.sideLength = 10;     // { color: 'blue', sideLength: 10 }

这里,Shape接口被Square接口所继承,所以自然Square接口多了一个属性color。

混合类型

有时期望使用接口同时描述对象的属性、方法等,可以如下:

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;

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏专知

2018年SCI期刊最新影响因子排行,最高244,人工智能TPAMI9.455

2018年6月26日,最新的SCI影响因子正式发布,涵盖1万2千篇期刊。CA-Cancer J Clin 依然拔得头筹,其影响因子今年再创新高,达244.585...

1482
来自专栏闵开慧

Failed to set permissions of path

12/09/04 16:46:34 INFO support.ClassPathXmlApplicationContext: Refreshing org...

2757
来自专栏码匠的流水账

聊聊HystrixThreadPool

hystrix-core-1.5.12-sources.jar!/com/netflix/hystrix/HystrixThreadPool.java

931
来自专栏Golang语言社区

Knapsack problem algorithms for my real-life carry-on knapsack

I'm a nomad and live out of one carry-on bag. This means that the total weight o...

1192
来自专栏一个会写诗的程序员的博客

java.base.jmod

/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/jmods$ jmod list java....

1182
来自专栏增长技术

App Guide相关

##TourGuide https://github.com/worker8/TourGuide

822
来自专栏Ryan Miao

ehcache报错

jfinal2.0+tomcat7+ehcache2.6.11+Linux Linux version 2.6.18-164.el5 (mockbuild@x8...

3749
来自专栏Hadoop数据仓库

Oracle sqlldr 如何导入一个日期列

1. LOAD DATA INFILE * INTO TABLE test FIELDS TERMINATED BY X'9' TRAILING NULLCO...

1876
来自专栏前端儿

Web 前端颜色值--字体--使用,整理整理

颜色值 CSS 颜色使用组合了红绿蓝颜色值 (RGB) 的十六进制 (hex) 表示法进行定义。对光源进行设置的最低值可以是 0(十六进制 00)。最高值是 2...

2762
来自专栏码匠的流水账

java9系列(五)Stack-Walking API

java9新增这个类的目的是提供一个标准API用于访问当前线程栈,之前只有Throwable::getStackTrace、Thread::getStackTr...

471

扫码关注云+社区