走进TypeScript之接口

初识

接口是一种数据类型,它好比一个名字,是对某一类数据对象的描述。区别于其他语言的接口,ts接口只注重外形,而不是实现。

interface LabelledValue {
  label: string;
}

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

let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);

可选属性和只读属性

使用 ?: 表示一个接口的属性可选,使用readonly关键字修饰接口属性,表示这个属性只读,即在初始化之后不能修改。

interface SquareConfig {
  color?: string;
  width?: number;
  readonly x: number;
  readonly y: number;
}

  延伸:数组只读用ReadonlyArray<T>来定义

let commonArr: number[] = [1, 2, 2, 3];
let onlyRead: ReadonlyArray<number> = commonArr;

// 想要将只读数组赋值给其他数组,只能类型断言
commonArr = onlyRead as number[];

属性检查

接口定义外的额外的属性,直接使用的时候,类型检查会报错。我们定义一个新变量再传入来跳过类型检查,或者直接使用类型断言。

interface labelValueInterface {
  label: string;
}
function printLabel2(labelValue: labelValueInterface) {
  console.log(labelValue.label);
}

printLabel({ label: "hello world, keep coding!" });

// error
// printLabel({ label: "hello world, keep coding!!!", type: "string" });

// 赋值给另一个变量,会跳过类型检查
let labelObj3 = { label: "hello world, keep coding!!!", type: "string" };
printLabel(labelObj3);

类型断言:

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

函数类型

函数类型的接口,只需要定义参数名称和类型和返回值类型。其中函数参数名称只是为了可读性强一点,并不是强制要求函数的参数名称与接口定义的相同。

根据类型推论,函数的参数类型也可以省略。

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];

类类型

接口描述了类的公共部分,而不会检查类的私有成员

类是具有两个类型的:静态部分的类型和实例的类型。类类型的接口只会检查其实例部分。

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

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

接口继承

接口可以使用extends关键字继承。

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

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 {
    select() { }
}

class Location {

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值