初识
接口是一种数据类型,它好比一个名字,是对某一类数据对象的描述。区别于其他语言的接口,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 {
}