学习教程:https://www.w3cschool.cn/typescript/typescript-interfaces.html
比如我写一段程序,打印出名字
function printPerson(person:{name:string}){
console.log(person.name)
}
let xiaozhang = {name: "张三",age:18,from:"China"}
printPerson(xiaozhang)
浏览器控制台就会输出:张三
声明了一个打印人名的printPerson函数,形参为person,接受的数据类型为{name:String},即接收一个对象,对象内有一个name属性,name类型为String。
用接口的形式改写一下:
interface Person{
name: string
}
function printPerson(person:Person){
console.log(person.name)
}
let xiaoli = {name: "李四",age:18,from:"China"}
printPerson(xiaoli)
定义一个叫Person的接口,接口里有一个name,类型为String
依旧是 printPerson函数,声明一个person形参,类型是Person接口定义的类型,以此看出来,接口就是来描述函数传参的类型的。
再对上述代码进行改写:
interface Person{
name:string
age?:number
}
function newPerson(person:Person): {name: string,age: number}{
let newPerson = {name:"",age:0}
if(person.name){
newPerson.name = person.name
}
if(person.age){
newPerson.age = person.age
}
return newPerson
}
let xiaozhang = {name:"张三",from:"England",like:"Eat"}
let xiaoli = {name: "李四",age:18,from:"China"}
console.log("The person's name is: " + newPerson(xiaozhang).name + " and the age is: " + newPerson(xiaozhang).age)
console.log("The person's name is: " + newPerson(xiaoli).name + " and the age is: " + newPerson(xiaoli).age)
1、接口里添加了一个age,age后面有一个?号。表示这个属性是可选的,就是传参数的时候,这个属性可以不传
2、函数后面添加了: {name: string,age: number},表示这个函数返回这样的一个对象。
3、可以发现,传入的参数可以不完全和接口定义的一样,但是必须有,比如非可选的name
4、注意!!,这里面有一个坑
xiaozhang作为一个变量是可以传的,如果直接将xiaozhang的对象传入,却会报错
因为接口里没有from和like
有三个方法解决这个问题:
1、毫无疑问,赋值给一个变量就不会出现这个问题。
2、添加类型断言(后面添加as 接口名)
3、添加字符串索引签名(接口里预留一个任何类型的的未命名属性)
再对上面代码进行改写
interface Person{
name:string
age?:number
readonly from?: string
}
function newPerson(person:Person): {name: string,age: number, from: string}{
let newPerson = {name:"",age:0, from: '未知的国家区域'}
if(person.name){
newPerson.name = person.name
}
if(person.age){
person.age = 6
newPerson.age = person.age
}
if(person.from){
person.from = "其他国家"
newPerson.from = person.from
}
return newPerson
}
let xiaozhang = {name:"张三",from:"England",like:"Eat"}
let xiaoli = {name:";李四",age:18}
console.log("xiaozhang come from: " + newPerson(xiaozhang).from + "and age is:" + newPerson(xiaozhang).age)
console.log("xiaoli come from: " + newPerson(xiaoli).from + "and age is:" + newPerson(xiaoli).age)
1、接口里增加了一个from属性,前面的readonly修饰符代表了这个属性只读,不能更改。后一个?代表了可选
2、在代码里,我们判断person.from如果有,就改成“其他国家”。这里你看不出报错,但是我使用VS code编辑器,其实已经报错了。
3、在代码里,我们判断person.age如果有,就改成6。
这是注释掉person.from = "其他国家"的运行结果
接口除了可以描述变量,还可以描述函数
比如,我们可以将上面的代码继续重写
interface Person{
name:string
age?:number
readonly from?: string
}
interface NewPerson{
(person: Person): {name: string,age: number, from: string}
}
let getNewPerson:NewPerson
getNewPerson = function(onePerson:Person){
let newPerson = {name:"",age:0, from: '未知的国家区域'}
if(onePerson.name){
newPerson.name = onePerson.name
}
if(onePerson.age){
onePerson.age = 6
newPerson.age = onePerson.age
}
if(onePerson.from){
//person.from = "其他国家"
newPerson.from = onePerson.from
}
return newPerson
}
let xiaowang = {name:"王五", aga: 17, from:"India"}
console.log("xiaowang come from : " + getNewPerson(xiaowang).from)
1、使用一个NewPerson来描述函数。参数是person,参数类型是Person,返回一个对象
2、声明一个变量,类型是NewPerson
3、getNewPerson是一个函数,参数是onePerson(不需要与接口一致),类型是Person