用于规范定义变量的类型,规定变量应该具有什么属性或函数入参什么值返回什么值等。
可选属性
带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个?符号。定义的属性可以不用实现。
只读属性
只读属性只能在对象刚刚创建的时候修改其值。在属性名前用readonly来指定只读属性。
interface Point {
readonly x: number;
readonly y: number;
}
let p1: Point = { x: 10, y: 20 };
p1.x = 5; // error!
表示数组创建后再也不能被修改
let a: number[] = [1, 2, 3, 4];
let ro: ReadonlyArray = a;
ro[0] = 12; // error!
ro.push(5); // error!
ro.length = 100; // error!
a = ro; // error!
注意最后a=ro,将ReadonlyArray赋值到一个普通数组也是不可以的。但是你可以用类型断言重写
a = ro as number[];
接口继承接口
一个接口可以继承多个接口,创建出多个接口的合成接口,继承的每个接口里的内容都需要满足。
interface Shape {
color: string;
}
interface PenStroke {
penWidth: number;
}
interface Square extends Shape, PenStroke {
sideLength: number;
}
let square:Square = {
color: 'bule',
sideLength: 0,
penWidth: 0
};
接口继承类
当接口继承了一个类类型时,它会继承类的成员但不包括其实现。就好像接口声明了所有类中存在的成员,但并没有提供具体实现一样。
例如下面接口继承了Control类,故接口约束的abc类中需要定义pubulic的state属性
class Control {
state: any;
}
interface SelectableControl extends Control {
select(): void;
}
class abc implements SelectableControl {
state: any
select() { }
}
注意接口也能继承到类的private和protected成员。但继承后这个接口类型只能被这个类或其子类所实现。
例如下面abc实现SelectableControl接口就必须是Control类的子类,因为state属性是私有属性。
class Control {
private state: any;
}
interface SelectableControl extends Control {
select(): void;
}
class abc extends Control implements SelectableControl {
select() { }
}
接口规范类
相当于用接口规范便量时的冒号:,同样也可以通过逗号用多个接口约束一个类。
注意接口中定义的属性,必须在初始时定义,如果仅在constructor中定义也会报错,例如下面h不能仅在constructor中定义
interface ClockInterface {
tick();
}
interface Clock {
h: number
}
class DigitalClock implements ClockInterface,Clock {
//h: string //放开此行注释为正确的
constructor(h: number, m: number) { } //error缺少h属性
tick() {
console.log('beep beep');
}
}
函数类型接口
括号里为参数,冒号右边为函数的返回值。
函数的参数会逐个进行检查,只要求对应位置上的参数类型是兼容的。所以函数的参数名不需要与接口里定义的名字相同。
interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch: SearchFunc = function(so: string, su: string) {
let result = so.search(su);
return result > -1;
}
可索引类型接口
可索引类型具有一个索引签名,它描述了对象索引的类型,还有相应的索引返回值类型。
它共有支持两种索引签名:字符串和数字。
注意同时使用两种类型的索引时,数字索引的返回值必须是字符串索引返回值类型的子类型。这是因为当使用number来索引时,JavaScript会将它转换成string然后再去索引对象。也就是说用100去索引等同于使用'100'去索引,因此两者需要保持一致。
class Animal {
name: string;
}
class Dog extends Animal {
breed: string;
}
interface NotOkay {
[x: number]: Animal;
[x: string]: Dog;
}// 错误:使用'string'索引,有时会得到Animal,数字索引应该是字符串索引的子集
interface NotOkay {
[x: number]: Dog;
[x: string]: Animal;
}//OK
注意使用了可索引类型后,另外定义的属性需要符合可索引。例如下面额外定义了字符串name属性,而使用的可索引也是字符串,所以指向的值应该相同。
interface NumberDictionary {
[index: string]: number;
length: number; // 可以,length是number类型
name: string // 错误,`name`的类型与索引类型返回值的类型不匹配
}
只读设置
可以将索引签名设置为只读,这样就防止了给索引赋值
interface ReadonlyStringArray {
readonly [index: number]: string;
}
let myArray: ReadonlyStringArray = ['Alice', 'Bob'];
myArray[2] = 'Mallory'; // error!
类类型接口
接口描述了类的公共部分,而不是公共和私有两部分。它不会检查类是否具有某些私有成员。
interface ClockInterface {
currentTime: Date;
}
class Clock implements ClockInterface {
private currentTime: Date;//error ,只能为public
constructor(h: number, m: number) { }
}
规定构造函数
注意类是具有两个类型的:静态部分的类型和实例的类型,constructor存在于类的静态部分,所以不在检查的范围内。
故下面通过在接口里new定义构造函数会报错
interface ClockConstructor {
new (hour: number, minute: number);
}
class Clock implements ClockConstructor { //error,接口中的new无法直接在类里面实现
currentTime: Date;
constructor(h: number, m: number) { }
}
但是我们可以借助函数的的形式去实现,例如下面
interface ClockInterface {
tick();
}
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');
}
}
interface ClockConstructor {
new (hour: number, minute: number): ClockInterface;
}
function createClock(ctor: ClockConstructor, hour: number, minute: number){
return new ctor(hour, minute);
}
let digital = createClock(DigitalClock, 12, 17);
let analog = createClock(AnalogClock, 7, 32);
混合类型接口
一个对象可以同时做为函数和对象使用,并带有额外的属性。
需要借助类型断言,例如下面:
文章为作者独立观点,不代表 股票程序化软件自动交易接口观点