# typescript(四) - 接口

# 接口

接口一方面可以在面向对象编程中表示为行为的抽象,另外可以用来描述对象的形状

# 约束对象

我们来看下如何使用接口来约束对象




 






interface SpeakInterface {
    speck(): void
    name: string
}

let man: SpeakInterface = {
    speck() { },
    name: 'chenying'
}

我们发现通过接口SpeakInterface约束的对象必须有speck方法和name属性

但是如果我们的对象有很多未知的属性的时候, 我们可以这样做




 






interface ObjInterface {
    name: string
    [propName: string]: any
}
let obj: ObjInterface = {
    name: 'chenying',
    eat() { },
    age: 18
}

通过 [propName: string]: any 来表示对象的其他属性的值是any

如果我们需要定义对象的某一个属性的值的类型的时候我们可以这样做




 




interface ObjInterface {
    [index: string]:string
}
let obj: ObjInterface = {
    name: 'chenying',
    age: 18 // 不能将类型“number”分配给类型“string”
}

我们通过接口约束对象属性的值只能是string

# 约束类

接口不仅可以约束对象, 在开发中我们经常用来约束类




 











interface SpeakAble {
    speck(): void
}
interface eatAble {
    eat(): void
}
class Man implements SpeakAble, eatAble {
    speck() { }
    eat() { }
}

class Lady implements eatAble {
    eat() { }
}

同样的, 被约束的类必须要有接口约束的属性。而且一个类可以受多个接口的约束。

# 约束函数

我们可以通过接口约束函数的参数类型和返回值类型




 




interface FnInterface {
    (num: number): number
}
let sum: FnInterface = function (num: number): number {
    return num
}
export { }

# 约束数组

我们可以通过以下巧妙的方法约束数组




 


interface ArrayInterface {
    [index:number]:string
}
let arr:ArrayInterface = [1,'2'] // he expected type comes from this index signature
let arr:ArrayInterface = ['1', '2']

我们可以理解为, 数组其实也是一个对象, 不过对象中的键是索引0~N , 所以我们可以通过[index:number]:string 来约束数组每一项的类型

# 接口可以继承接口

看完了日常开发中接口的用法,我们来看下接口的一些特殊用法




 








interface SpeakiInterface {
    speck(): void
}
interface EatInterface extends SpeakiInterface {
    eat(): void
}

class Person implements EatInterface {
    speck() { }
    eat() { }
}

代码中接口EatInterface继承了接口SpeakiInterface, 所以等同于类Person受两个接口约束

# 接口中使用readonly




 





interface SpeakiInterface {
    readonly name: string
    speck(): void
}
let man1: SpeakiInterface = {
    name: 'chenying',
    speck() { }
}

被接口约束的readonly属性是只读的