作为一个小职员,工作多,没提成,人家休假我加班。房贷没还清,保险自己买。不过好在我不用交停车费,因为我根本买不起车。2020年小编决定好好的学习Typescript,提升个人能力,努力赚小钱钱,争取买到一辆自行车(呸,要啥自行车!!!!)。这是小编写的第四篇Typescript学习的文章。
最近同事王七比较牛逼,天天开一个劳斯莱斯来上班,就他那点工资,都不够油钱,可是人家就这么牛逼。后来打听了一下,原来是他女朋友铁锤仙子送的。据说铁锤仙子过生日的那天,他表现的特别好,铁锤仙子一高兴,就送他一辆车,也是幸福啊。人家女朋友是真有钱,俗话说,女大三,抱金砖,他女朋友足足报了15块金砖。
接口定义
这不,有一天王铁锤仙子给王七说,你看你哥哥弟弟(你懂得哈)们也多,我年龄大了,有时候记不清楚谁是谁,你给我做一个男朋友管理系统吧,这是一百万,你先花着,不够再说啊。 王七一想,男朋友管理系统,先定义一个男朋友的对象吧。
// 男朋友接口
interface IBoyFriend {
id: string,
name: string,
age: number,
height: number,
weight: number,
// 就不注释了
time: number,
duration: number,
photo: string
}
// 定义一个男朋友
const boyFriend: IBoyFriend = {
id: string,
name: '王七',
age: 25,
height: 180,
weight: 75,
time: 2,
duration: 15,
photo: 'http://xxxxxxxxxx.jpg'
}
// 新增方法
function add(boyFriend: IBoyFriend): void {
// do something
}
// 抹杀方法,肯定不是删除那么简单了
function obliterate(boyFriend: IBoyFriend): void{
// do someting
}
// 查询方法
function list(): IBoyFriend[] {
return [boyFriend]
}
可选属性与只读属性
这两天铁锤仙子有点兴奋,新认识了一个外国小哥,体验贼好了。可是想把小哥录入系统时候,发现没有地方指定小哥的国籍的。就让王七给加一下王七脑子一转,三下五除二就写了下面的代码
interface IBodyFriend{
name: string,
// 其他省略
...,
// 国籍
nationality?: string
}
// 定义一个男朋友
const boyFriend: IBoyFriend = {
id: '1'
name: '王七',
age: 25,
height: 180,
weight: 75,
time: 2,
duration: 15,
photo: 'http://xxxxxxxxxx.jpg',
nationality: '中国'
}
function add(boyFriend: IBoyFriend): void {
// 如果不选,默认为中国
if(boyFriend.nationality === undefiend) {
boyFriend.nationality = '中国'
}
// do someting
}
对于可选属性,即使不赋值也不会报错。
const obj = Object.freeze({score: 0})
王七功能做完了,屁颠屁颠去给铁锤表功,没想到又挨了一顿骂,原来是铁锤想查找其他人信息,确一直显示王七的信息,功劳没有拿到,又有活干了,王七检查了一下代码,发现了这样一段代码
// 王七把自己的id写死成1了
if(user.id = '1') {
// 给自己美言几句话
} else {
// 偷偷的贬低别人
}
原来是把===
写成了=
,那应该如何避免这类问题了,王七想到了只读属性
interface IBoyFriend{
readonly id: string
}
对于只读属性,只能在初始化对象赋值的时候赋值,不能在中间过程中修改值
多余属性检查
有时候虽然接口定义了一系列属性,但实际上外部传入的属性可能会比定义的属性要多,就拿王七定义的男朋友接口来说,有name
,age
啥的,但是铁锤仙子的闺蜜给她推送了一批新的数据
const data: IBoyFriend[] = [{
id: '2'
name: '王八',
age: 25,
height: 180,
weight: 75,
time: 2,
duration: 15,
photo: 'http://xxxxxxxxxx.jpg',
nationality: '坦桑尼亚',
// 多余的属性
// 报错 Object literal may only specify known properties, and 'birthday' does not exist in type 'IBoyFriend'.
birthday: 'xxxx-xx-xx',
sex: '女'
}]
这时候因为IBoyFriend里面没有定义多余的属性,所以会报错,对于这些不属于接口的数据,可以通过多余属性检查来避免报错
interface IBodyFriend{
name: string,
// 其他省略
...,
// 额外的属性检查
[propName: string]: any
}
函数类型
接口可以描述对象拥有的各种各样的外形,除了带属性的普通对象外,还可以定义函数的外形。 下面就是王七定义的根据国籍查询列表的函数
// 定义函数类型
interface ISearchByNation {
// 冒号左侧为参数类型,右侧为返回值类型
(nation: string): IBoyFriend[]
}
const search: ISearchByNation = (nation) => {
return []
}
有时候在定义函数的时候,还需要绑定一些额外的属性,比如我们希望一个按钮事件,如果300毫秒内重复点击,则不触发
interface IClick {
(e: Event): void,
// 额外的属性
timer?: number
}
const click: IClick = (e) => {
if (click.timer) {
return
}
// do something
click.timer = setTimeout(() => {
click.timer = undefined
},300)
}
类类型
铁锤仙子最近带着王七参加了几次车展,买了几辆兰博基尼,劳斯莱斯,林肯,奔驰啥的。每天开着豪车去外面潇洒玩游戏也感觉挺不错的。
// 定义一辆车的类型
interface ICar {
// 品牌
brand: string,
// 型号
modelNumber: string,
// 开车
drive(): void,
// 玩游戏
play(): void
}
/**
* 对于类类型来说,接口只会定义类的公共部分的内容,比如`brand`,`drive`,并不会管其他的属性或方法,如下面的`other`,`otherMethod`
*/
class Car implements ICar {
brand = ''
modelNumber = ''
// 其他信息
other = ''
otherMethod() { }
constructor(brand: string, modelNumber: string) {
this.brand = brand
this.modelNumber = modelNumber
}
drive() {
// 开车
}
play() {
// 玩游戏
}
}
const car = new Car('奔驰', '梅赛德斯-AMG C 63')
// 开车
car.drive()
// 玩游戏
car.play()
土豪出门会开一辆车吗,不可能,都是要出动车队的
/**
* 当你操作类和接口的时候,类是具有两个类型的:静态部分的类型和实例的类型
* 当定义一个类接口的时候,其实只定义了类的实例部分, 如上 ICar
* 当需要操作类的时候,需要定义类的静态部分,如下
*/
interface ICarContructor{
new(brand:string, modelNumber: string): any
}
// 定义车队
function motorcade(CarCont: ICarContructor, brand:string, modelNumber:string): void {
const car = new CarCont(brand, modelNumber)
// 开车
car.drive()
// 玩游戏
car.play()
}
motorcade(Car, '奔驰', '梅赛德斯-AMG C 63')
motorcade(Car, '兰博基尼', 'Huracan')
接口继承
/**************王七出差去美国和建国同志聊天去了*******************/
和类一样,接口也可以相互继承,这让我们能够从一个接口里复制成员到另一个接口里,可以更灵活地将接口分割到可重用的模块里。
interface IHuman{
sex: string,
name: string,
height: number,
weight: number
}
interface IWoman extends IHuman {
// 撒娇
coquetry(): void,
// 卖萌
actingCute(): void
}
interface IMan extends IHuman{
makeMoney(): void
}