TypeScript 系列(五)—— 接口

62 阅读3分钟

利用接口对上面的代码进行改造一下:

interface objValue {

name:string

age:number

}

function foo(obj:objValue) {

console.log(My name is ${obj.name},${obj.age} years old)

}

foo({name:'jonas',age:18})

通过上面的接口的约束,参数 obj 必须按照接口中的规定来,若不一致则会报错。

可选属性

====

在上面的例子中,在函数调用时必须传入接口中所有声明了的属性,缺一不可,换句话说,上面例子定义的都是必需的属性。有时候,我们期望某些属性是可选的,也就是说,某些属性不是必须的。这时候就得配置可选属性了,配置的方式很简单,只需要在属性后面加上一个 ? 即可。

interface objValue {

name:string

age:number

gender?:string //这就是可选属性

}

function foo(obj:objValue) {

console.log(My name is ${obj.name},${obj.age} years old)

}

foo({name:'jonas',age:18})//不会报错

foo({name:'jerry',age:18,gender:'female'})

只读属性

====

如果期望对象的属性初始化后就不被修改,那么就可以使用可读属性。通过关键字 readonly 来声明接口中的属性就表示该属性只读,一旦初始化则不能修改。

interface objValue {

readonly name:string

age:number

gender?:string

}

let obj:objValue = {name:'jonas',age:18}

obj.name = 'jerry'//报错

另外,此处介绍一个只读数组:一旦初始化,数组中的元素不能被修改。ReadonlyArray 这是一个预定义的类,可以直接使用:

let arr:ReadonlyArray = [1,2,3,4]

arr[0] = 0 //报错

注意,接口将所有数组的方法去除了,所以上面这个数组也不能调用普通数组的方法进行修改!!

额外的属性

=====

在前面提到默认定义的是必须属性,属性后面加上?的是可选属性,属性前面加上 readonly 关键字的是只读属性。接下来介绍的是额外属性,额外属性就是在接口定义范围以外的属性。

interface objValue {

readonly name:string

age:number

gender?:string

}

let obj:objValue = {name:'jonas',age:18,address:'china'}//报错!!

这个报错就在于我们加上了 address 这个属性,或许你会理所当然的认为这不该报错,可是 TS 就偏不按你想的来。如果允许传入一些自定义属性,那么最笨的方法当然是在接口中逐一定义,但是有可能你不知道未来加入的属性名是什么,那么此时就需要配置额外属性了。

配置的方式很简单,直接在接口中加上一行:

interface objValue {

readonly name:string

age:number

gender?:string

}

let obj:objValue = {name:'jonas',age:18,address:'china'}//这下就好了

前面提到的都是对对象的约束,接口除了可以约束对象的属性以外,还可以对函数进行约束。

通过接口来约束函数就跟 Java 中的接口是一致的,在接口中声明一个函数的签名就可以了。

语法:(形参列表):返回值

interface PersonInterface {

(name:string,age:number):string

}

let person:PersonInterface = function (name: string, age: number) {

return My name is ${name},${age} years old.

}

person('jonas',18)

通过类实现接口

=======

在 Java 中,接口都是被类实现的,接口相当于一个类的抽象层,而实现类才是这个接口的具体实现。在 TS 中,接口也能被类实现。

interface PersonInterface {

name:string

age:number

sayHi(name:string,age:number):string

}

class Person implements PersonInterface{

age: number;

name: string;

sayHi(name: string, age: number): string {

return My name is ${name},${age} years old;

}

}

需要注意的是,接口描述的是类的公共部分,不会描述私有的部分。

接口之间的继承

=======

在 Java 中,类之间的继承是单继承的,也就是说,一个类只能继承另外一个类,而不能继承多个类,但是接口之间的继承就是多继承的。一个接口可以继承多个接口。在 TS 中,接口也是可以多继承的。

接口的继承本质上就是将继承接口中的所有东西搬过来而已,这是很纯粹的继承。