#接口

接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法。
在typescript中接口可以这样理解,只定义属性的类型或者方法的参数类型和返回值类型,至于具体的值是什么,接口不关心,只需要类型保持一致,符合接口的类型约定。

接口定义

使用关键字interface

interface interface_name {
	
}
interface Fb { 
    foo:string, 
    bar:string, 
    sayHi: function():string {
			return 'hello typescript'
		}
} 

var customer:Fb = { 
    firstName:"Tom",
    lastName:"Hanks", 
    sayHi: ():string =>{return "Hi there"} 
} 

可选属性

定义可选属性使用?:,接口中只要定义了可选属性,就可以认为使用了“option bags”模式

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"});

只读属性

定义只读属性使用readonly

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

只读属性在实现接口后(初始化后)不能对属性进行重新赋值

额外的属性检查

当使用option bags模式式,需要注意额外的属性检查。

interface SquareConfig {
    color?: string;
    width?: number;
}

function createSquare(config: SquareConfig): { color: string; area: number } {
    // ...
}

let mySquare = createSquare({ colour: "red", width: 100 });  //error: 'colour' not expected in type 'SquareConfig'

解决方式

  • 类型断言
    let mySquare = createSquare({ width: 100, opacity: 0.5 } as SquareConfig);
    let mySquare = createSquare(<SquareConfig>{ width: 100, opacity: 0.5 }  );
    

函数类型

interface SearchFunc {   //抽象声明
  (source: string, subString: string): boolean;
}

let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {   // 具体实现	
  let result = source.search(subString);
  return result > -1;
}

索引类型

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

let myStr: string = myArray[0];

:::warning
TypeScript支持两种索引签名:字符串和数字。 可以同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值类型的子类型。 这是因为当使用 number来索引时,JavaScript会将它转换成string然后再去索引对象。
也就是说用 100(一个number)去索引等同于使用"100"(一个string)去索引,因此两者需要保持一致
:::
比如

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

// 错误:使用数值型的字符串索引,有时会得到完全不同的Animal!
interface NotOkay {
    [x: number]: Animal;  // error 数字索引类型“Animal”不能赋给字符串索引类型“Dog”
    [x: string]: Dog;
}
// 正确
interface NotOkay {
  [x: number]: Dog;
  [x: string]: Animal;
}

类类型

实现接口

implements关键字创建一个接口类

interface ClockInterface {
    currentTime: Date;
}

class Clock implements ClockInterface {   //Clock是一个接口类,需要实现ClockInterface接口
    currentTime: Date;
    constructor(h: number, m: number) { }
}

在接口中描述一个方法

interface ClockInterface {
    currentTime: Date;
    setTime(d: Date);
}

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

constructor属于类的静态部分,typescript不会对静态部分进行检查

继承接口

使用关键字extends

单个继承

interface Shape {
    color: string;
}

interface Square extends Shape {
    sideLength: number;
}

let square = <Square>{};
square.color = "blue";
square.sideLength = 10;

多继承

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;

混合类型

一个接口同时作为对象和函数使用

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;

接口继承类

class Control {
    private state: any;
}

interface SelectableControl extends Control {
    select(): void;
}

class Button extends Control implements SelectableControl {
    select() { }
}

class TextBox extends Control {
    select() { }
}

// 错误:“Image”类型缺少“state”属性。
class Image implements SelectableControl {  //Image不是Control的子类,所以无法实现SelectableControl
    select() { }
}

class Location {

}

在上面的例子里,SelectableControl包含了Control的所有成员,包括私有成员state。
因为 state是私有成员,所以只能够是Control的子类们才能实现SelectableControl接口。
因为只有 Control的子类才能够拥有一个声明于Control的私有成员state,这对私有成员的兼容性是必需的。
在Control类内部,是允许通过SelectableControl的实例来访问私有成员state的。 实际上,
SelectableControl接口和拥有select方法的Control类是一样的。 Button和TextBox类是SelectableControl的子类
(因为它们都继承自Control并有select方法),但Image和Location类并不是这样的。

脑图

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值