利用接口对上面的代码进行改造一下:
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 中,接口也是可以多继承的。
接口的继承本质上就是将继承接口中的所有东西搬过来而已,这是很纯粹的继承。