网站建设 印花税,合肥公司注册平台,网站内容填写,西安惠安小学网站建设目录
前言
定义
用法
基本用法
约定规则
属性控制
任意属性
可选属性
只读属性
定义函数
冒号定义
箭头定义
接口类型
函数接口
索引接口
继承接口
类接口
总结 前言
在介绍TS对象类型中#xff0c;为了让数组每一项更具体#xff0c;我们使用 string [ ]…目录
前言
定义
用法
基本用法
约定规则
属性控制
任意属性
可选属性
只读属性
定义函数
冒号定义
箭头定义
接口类型
函数接口
索引接口
继承接口
类接口
总结 前言
在介绍TS对象类型中为了让数组每一项更具体我们使用 string [ ] 表示字符串类型的数组为了知道函数的参数与返回值使用 let fn: (a: number, b: number) number 来表示一个函数类型那么作为复杂类型仅仅使用Object表示一个普通对象类型是远远不能满足类型检查以及代码可读性的有没有一种类型可以用来描述对象的结构呢
这便是今天的主题接口
定义
接口Interface是一种定义对象形状的方式它指定了对象具备或拥有哪些属性和方法可以用来定义对象属性值和属性名的类型。使用接口来定义对象可以使代码更健壮清晰。与Java的接口不同TS接口除了能够描述类还可以描述对象函数等。
用法
基本用法
接口使用interface作为关键词与JS中类class的写法相似下面是一个JS类
class Animal {color black;showColor () this.color
}
console.log(new Animal().showColor());
我们定义了一个Animal类其中包含1个属性以及1个行为那么在我们抽象构想这个类时可能只知道它的类型比如color可能是字符串类型showColor函数返回一个颜色字符串
接口的写法如下
interface 接口名称 {属性名: 属性类型函数名(参数类型列表): 返回值类型
}
让我们稍作改动用接口的方式实现这个类
interface Animal {color: stringshowColor: () string
}
怎么样是不是觉得接口不算太难只需要仿照class的写法将类抽象成类的形状属性的类型就可以实现一个接口
参照之前基本类型的写法我们新增一个对象使用对象实现这个抽象的接口
interface Animal {color: stringshowColor: () string
}const animal: Animal {color: blue,showColor() {return this.color},
}
console.log(animal.showColor());约定规则
一般我们定义接口时命名规则是在名称前加 I 即上述接口名是IAnimal
在使用接口定义对象时会遇到属性不匹配的情况比如上述代码我们改成
const animal: Animal {color: black,name: dog,showColor() {return this.color},
}
此时编辑器会提示 name 不在类型 Animal 中 那么我们去掉name和color只保留showColor函数呢
const animal: Animal {showColor() {return this.color},
}
编辑器会提示类型中缺少属性 color。
或者我们不想修改animal中的color属性让它始终是black
那么有没有办法使接口支持上述属性的操作呢请接着往下看
属性控制
在接口中每个属性都有3种选项分别是可选只读任意换句话说接口中的属性可以设置成可变的。
任意属性
在接口定义时在属性名后面加上索引签名来表示接口可以有任意数量的属性。如
interface Animal {color: stringshowColor: () string[key: string]: unknown
}
这个接口可以匹配约定规则中的第一段代码
tips索引签名参数上述代码的key类型支持numberstringsymbol模板字符示例如下
interface Animal {[key: symbol | string | number]: unknown
}
const str name
const animal: Animal {0: dog,[str]: dog,[Symbol(name)]: dog,
}可选属性
在定义接口时我们可能无法判断某个属性是否存在。此时一个可选的属性操作可以为我们解决此问题我们在属性名后面增加一个 ? 问号用于为属性增加可选操作如
interface Animal {color?: string
}
const animal: Animal {color: black
}
const animal2: Animal {}
此时color属性在对象中便可有可无这个接口可以适配约定规则中的第二段代码。
只读属性
顾名思义只读属性保证了对象中某个属性只允许读取不允许修改
interface Animal {readonly color: string
}
const animal: Animal {color: black
}
animal.color white
上述代码中会在编译前报错无法分配到 color 因为它是只读属性
在JS中我们同样可以控制对象中属性的只读即只设置属性get而不使用set操作代码如下
const animal {_color: black,get color() {return this._color}
}
animal.color white
定义函数
函数在接口中有两种表现形式分别是冒号定义和箭头定义
冒号定义
interface 接口名 {函数名 (参数类型) : 函数返回类型
}
箭头定义
interface 接口名 {函数名: (参数类型) 函数返回类型
}
接口类型
接口除了上述展示的对象接口外还有函数接口索引接口继承接口类接口下面我会一一列举。
函数接口
在对象类型中我们说到了函数类型的定义的方式有两种分别是Function关键词和 ( )void 箭头函数那么在本文我们会接触到第三种定义函数的方式接口
interface IFn {(): void
}
我们通过上述代码实现一个无返回值的函数接口冒号:前面的括号表示参数后面表示函数返回值结合之前的知识我们写一个加法函数
interface IFn {(a: number, b: number): number
}
const add: IFn (a, b) {return a b
}
索引接口
同样在对象类型文章中我们提到了使用接口定义数组类型
interface IArray {[i: number]: any
}
通过定义索引值 i 的类型为 number 来描述一个数组类型
interface IArray {[i: number]: string
}
const list: IArray [a, b, c]
继承接口
和JS中的类一样接口类型也可以继承操作被继承的接口拥有父接口的属性及方法
interface IAnimel {name: string
}
interface IDog extends IAnimel {likeMeat: boolean
}interface IWhiteDog extends IDog {color: string
}const whiteDog: IWhiteDog {name: 阿黄,likeMeat: true,color: white
}
上述代码实现了一个连续的接口继承子类IWhiteDog拥有父类的属性。
继承接口与继承类不同接口可以通过多继承实现上述代码可以修改为以下代码
interface IAnimel {name: string
}
interface IDog {likeMeat: boolean
}interface IWhiteDog extends IAnimel, IDog {color: string
}const whiteDog: IWhiteDog {name: 阿黄,likeMeat: true,color: white
}
需要注意的是执行多继承时父接口的属性值可以重复但类型必须相同
interface IAnimel {name: stringlikeMeat: string
}
interface IDog {likeMeat: boolean
}interface IWhiteDog extends IAnimel, IDog {color: string
}
上述代码会抛错IAnimel 和 IDog 类型的命名属性 likeMeat 不完全相同
除了上面的继承接口外TS还有一类继承那便是接口继承类TS与其他面向对象语言不同它支持接口继承类中的属性类型及函数类型
将前面的代码修改一下便可以达到和上面的代码一样的效果实现接口对类的继承
class IAnimel {name 阿黄
}
class IDog {likeMeat true
}interface IWhiteDog extends IAnimel, IDog {color: string
}const whiteDog: IWhiteDog {name: 阿黄,likeMeat: true,color: white
}
需要注意的是接口继承的是类的接口可以理解为声明类的同时会创建类实例的接口类型这个接口类型被当做是类的接口所以接口继承的类实际上是类实例的接口
我们使用以下代码可以证实上面的说法
class IDog {static _likeMeat truelikeMeat false
}interface IWhiteDog extends IDog {color: string
}const whiteDog: IWhiteDog {likeMeat: true,_likeMeat: true,color: white
}
上述代码的抛错 说明接口可以继承类实例的属性却不可以继承类中的静态属性
类接口
接口是一种抽象的类型它的作用是描述对象的形状增强可读性和可维护性。在接口与类之间TS提供了一个 实现 implements关键词区别于传统的冒号赋予类型下面是一个类接口的例子
interface IAnimel {name: stringreadonly color: stringgetColor: () stringgetName?(): string
}
class Animal implements IAnimel {name dogcolor blackgetColor () this.color
}看到这里不知道你是否会有疑问接口可以描述类中的属性那是否可以对构造函数进行描述
答案是可以但是和常规写法稍有不同。我们在接口中使用new表示类中的constructor
interface IAnimel {name: stringnew(name: string): Animal
}
然而上面接口的写法无法使用类来实现
interface IAnimel {name: stringnew(name: string): Animal
}
class Animal implements IAnimel {name: string;constructor(name) {this.name name}
} 为什么会抛错呢
参考之前的一篇文章JS继承因为在TS的类型中类的构造函数和实例是两个不同的类型构造函数是一个特殊的函数它在创建类的实例时被调用并返回一个该类的实例类的实例则包含了类的所有属性和方法
有没有使我们实现接口的同时对构造函数进行描述的方法呢
且看下面的代码
interface IAnimel {// 描述实例name: string
}
interface IAnimelConstructor {// 描述构造函数new(name: string): Animal
}
class Animal implements IAnimel {// 实现接口name: string;constructor(name) {this.name name}
}
const createAnimal (__Animal: IAnimelConstructor): IAnimel {// 工厂模式解决接口的局限性return new __Animal(dog)
}
const animal createAnimal(Animal)
console.log(animal);
代码中我使用两个接口来描述一个类的构造函数及实例使用工厂模式解决接口的局限
总结
本文讲述了TypeScript中的接口类型从定义意义用法属性特性继承接口实现及局限性这几个方面详细的介绍了接口通过代码案例了解其具体用法
感谢你看到了这里如果文章对你有帮助希望支持一下博主谢谢。
参考文章
TypeScript 入门教程
Introduction - TypeScript 精通指南