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 条评论
登录 后参与评论

相关文章

来自专栏编码小白

ofbiz实体引擎(七) 检查数据源

/** * Check the datasource to make sure the entity definitions are correct,...

2604
来自专栏Java爬坑系列

【Java入门提高篇】Day13 Java中的反射机制

  前一段时间一直忙,所以没什么时间写博客,拖了这么久,也该更新更新了。最近看到各种知识付费的推出,感觉是好事,也是坏事,好事是对知识沉淀的认可与推动,坏事是感...

3459
来自专栏禹都一只猫博客

Pandas文本数据处理 | 轻松玩转Pandas(4)

562
来自专栏编码小白

tomcat源码解读三(2) tomcat中JMX的源码分析

     在这里我是将tomcat中的jmx给拆分出来进行单独分析,希望通过此种方式能够尽可能的出现更多的问题,以便对其有更多的了解,首先需要声明的是tomca...

4215
来自专栏风中追风

如何控制线程的执行顺序

控制线程的执行顺序有两种办法,通常来说,最简单的就算用Thread类提供的API,使用join方法即可。其使用方法及原理:深入理解join方法的底层原理 还有...

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

写了多年的Java,直到看到Kotlin,原来代码可以如此优雅!

如果你是像我一样是一名 优秀 的Java开发者 _ ,而且已经想用kotlin来实现你的程序,那么,抱歉!不要用Java的语法思维来写Kotlin,不要让kot...

1344
来自专栏编程之旅

Swift学习笔记(二)

743
来自专栏全栈架构

抱歉!不要用Java的语法思维来写Kotlin

如果你是像我一样是一名 优秀的Java开发者 ^_^,而且已经想用kotlin来实现你的程序,那么,抱歉!不要用Java的语法思维来写Kotlin,不要让kot...

674
来自专栏西安-晁州

js各种继承方式汇总

js中的各种继承实现汇总 首先定义一个父类: function Animal(name) { this.name = name || '动物' this...

3076
来自专栏Java进阶

如何控制线程的执行顺序

34216

扫码关注云+社区