一、介绍
TypeScript的核心原则之一是对值所具有的结构进行类型检查。接口的作用就是这些类型名称和为你的代码或第三方代码定义契约。
和C#中一样,接口定义规则,不定义实现。不同的是TypeScript这种的接口更灵活,用法比较多。
//定义接口
interface LabelledValue {
label: string;
}
function printLable(labeledObj: LabelledValue) {
console.log(labeledObj.label);
}
let myObj = {
size: 10,
label: '张三丰'
}
printLable(myObj);
二、接口的定义
1.可选属性
注: 使用?指定‘option bags’模式,指定属性非必须
//定义接口,可空属性,默认值等处理
//特别说明:
//1.接口可空属性不能全部为空
//2.传入的接口变量,不能还有其他非接口定义的变量
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:'blue'});
console.info(mySquare);
2.只读属性,使用readonly
//定义接口,只读属性
interface Point{
readonly x:number;
readonly y:number;
}
let p1:Point={x:10,y:20};
console.info(p1);
// p1.x=5; //编译宝座,不能对只读属性复制
3.额外的属性检查,指定某个属性为Any类型,则可以使用额外属性创建接口对象
interface SquareConfig {
color?: string;
width?: number;
[name:string]:any;
}
4.函数类型
//接口中使用 函数类型
interface SearchFunc {
(srouce: string, substring: string): boolean;
}
//接口实现中的变量名,不一定要和接口函数中的方法名相同
let mySearch: SearchFunc;
mySearch = function (src: string, sub: string): boolean {
let result = src.search(sub);
return result > -1;
}
console.log(mySearch('abcde','abc'));
// let mySearch2:SearchFunc;
// mySearch2=function(src,sub){
// //编译异常,指定的类型和接口中对应的类型不相同
// }
5.可索引的类型
//可索引的类型
//1.共支持两种索引签名:字符串和数字
//2.字符串索引签名能够很好的描述dictionary模式,可以使用obj.property和obj['property']访问操作
//3.将索引签名设置只读,这样可以方式使用索引赋值操作
interface StringArray {
[index: number]: string;
}
let myArray: StringArray;
myArray = ['Red', 'Blue'];
let myStr: string = myArray[0];
console.info(myArray);
console.info(myArray[0]);
class Animal {
name: string;
}
interface IAnimal {
[x: string]: Animal
}
let animal1: IAnimal;
let name1: Animal = { name: '张丹峰' };
animal1 = { '1': name1 }
console.info(animal1);
console.info(animal1['1']);
三、接口的实现
注:1.接口能多继承
2.接口混合类型使用可以作为对象,可以作为函数
3.类静态部分与实例部分的区别
当你操作类和接口的时候,你要知道类是具有两个类型的:静态部分的类型和实例的类型。 你会注意到,当你用构造器签名去定义一个接口并试图定义一个类去实现这个接口时会得到一个错误
1.类继承接口
//实现接口
interface ClockInterface {
currentTime: Date;
setTime(d: Date);
}
class Clock implements ClockInterface {
setTime(d: Date) {
this.currentTime = d;
}
currentTime: Date;
constructor(h: number, m: number) { }
}
2.接口继承接口
interface ClockConstructor {
new (hour: number, minute: number): ClockInterface;
}
interface ClockInterface {
tick();
}
function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface {
return new ctor(hour, minute);
}
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");
}
}
let digital = createClock(DigitalClock, 12, 17);
let analog = createClock(AnalogClock, 7, 32);
3.接口继承类
当接口继承了一个类类型时,它会继承类的成员但不包括其实现。 就好像接口声明了所有类中存在的成员,但并没有提供具体实现一样。 接口同样会继承到类的private和protected成员。 这意味着当你创建了一个接口继承了一个拥有私有或受保护的成员的类时,这个接口类型只能被这个类或其子类所实现(implement)