Interface(接口分享)第一节
一、接口初探
- 有时候我们传入的参数可能会包含很多的属性,但是编译器只会检查那些必须的属性是否存在,以及类型是否匹配,而咱们要讲的接口其实就是用来描述下面这个例子里的结构,对于接口传入的数据咱们只关心它的外形,只关心他传入的对象是够满足咱们接口的限定条件,满足咱们就认定他是正确的
function Animal(config: {name: string, age: number}) {
console.log("我叫:" + config.name + "今年" + config.age + "岁了")
}
console.log(Animal({ name: "yxl", age: 24 }))
// 下面重构
interface Config {
name: string
age: number
}
function Animal(config: Config) {
console.log("我叫:" + config.name + "今年" + config.age + "岁了")
}
/*
* 这里把接口限制的类型付给了变量myAnimal,即使咱们传入了接口中没有限制的属性,
* 这里编译之后也不会出现报错,是因为接口类型检查不会对变量赋值进行检查
* 如果咱们这里把Animal({name: "yxl", age: 24, color: "黑色的头发"})这样传参的话,
* 接口类型检查会报出当前color属性没有在Config接口中进行限制,所以是不被允许的
*/
let myAnimal = { name: "yxl", age: 24, color: "黑色的头发" }
console.log(Animal(myAnimal))
二、可选属性
- 接口里的属性有时候不是必须的,有的咱们可以用到,有的 用不到,这个时候可选属性接口就是一个不错的选择,可选属性的好处就是咱们可以对可能存在的属性进行预先定义,其次是能够捕获不存在属性是的一个错误
interface Config {
name: string
age?: number
// [propName: string]: any 字符串索引签名
}
function Animal(config: Config) {
console.log("我叫:" + config.name + "今年" + config.age + "岁了")
}
/*
* 这里将Animal传参中的age咱们故意打错了个字母,这个时候你就会发现当前接口会对这个属性进行检查
* 接口会对当前ages报错,不存在于当前接口规范中,这个时候为了避免这种报错可以采用类型断言,告诉这个接口,
* 当前穿的参数就是你的规范,这个时候可以发现错误消失了,还有另一种方法是通过索引签名的方式进行屏蔽错误
* [propName: string]: any 这个索引签名就是为了你能够预见某个对象可能觉有某些特殊的用途而准备的。
*/
console.log(Animal({ name: "yxl", ages: 24 } as Config))
三、只读属性
- 一些对象属性只能在对象刚刚创建的时候修改其值。 你可以在属性名前用 readonly 来指定只读属性:
interface Point {
readonly x: number
readonly y: number
}
let p:Point = { x: 12, y: 14 }
p.x = 15 // 错误
/*
* TypeScript 具有 ReadonlyArray<T> 类型,它与 Array<T> 相似,只是把所有可变方法去掉了,
* 因此可以确保数组创建后再也不能被修改:
*/
let a: number[] = [1, 2, 3]
let aa: ReadonlyArray<number> = a
aa[0] = 14; // Index signature in type 'readonly number[]' only permits reading.
aa.push(4) // Property 'push' does not exist on type 'readonly number[]'.
aa.length = 10 // Cannot assign to 'length' because it is a read-only property.
a = aa as number[] // 类型断言为数字组成的数组
a[0] = 15
四、函数类型
- 接口能够描述JavaScript中对象拥有的各种各样的外形。除了描述带有属性的普通对象外,接口也可以描述函数类型。接下来我们一起看一下函数类型接口是怎么使用的
interface SearchFun {
(source: string, subString: string): Boolean
}
let mySearch: SearchFun // @1
/*
* 这里对声明了一个匿名函数,并且将这个匿名函数付给了变量mySearch,并且同时
* 给这个匿名函数进行了传参,当然这个传参遵循了SearchFun接口规范,
* 接口会自动推断参数的类型,因为咱们已经将mySearch函数付给了SearchFun类型变量
* 注意: 函数类接口不同于属性类接口,要求属性的变量相同,这里变量可以不同,只需要保证变量的类型为string就行
* function(a, b): Boolean
* mySearch = function (a, b): Boolean { 这个方案也可,因为@1中已经将函数付给了接口类型变量
* */
mySearch = function (source: string, subString: string): Boolean {
let result = source.search(subString);
return result > -1
}
console.log(mySearch("http://b28.sy.souyoung.com/ad/cpcAuction", "28")) // true
五、可索引类型
- TypeScript 支持两种索引签名:字符串和数字。 可以同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值类型的子类型。 这是因为当使用 number 来索引时,JavaScript 会将它转换成string 然后再去索引对象。 也就是说用 100(一个 number)去索引等同于使用'100'(一个 string )去索引,因此两者需要保持一致。接下来看看如何使用:
/*
* 第一种情况数字类型索引NumberArr的时候返回值是string 这个时候调用a[0] 得到了Bob
* [index: number]: string
* 第二种情况是字符串索引NumberArr的时候返回值是string or number,这个时候
* 返回值是string调用:a["name"] 得到了Bob 返回值是number调用:a["name"] 得到
* 了数字:1
* [index: string]: string
* let a: NumberArr = {
* "name": "Bob"
* }
* * [index: string]: number
* let a: NumberArr = {
* "age": 24
* }
* */
interface NumberArr {
[index: number]: string
}
let a: NumberArr = ["Bob", "Jerry"] // 可
// let a: NumberArr = [55, 66] 不可
console.log(a[0]) // 可
class Animal {
name: string
}
class Dog extends Animal {
breed: string
}
interface NotOkay {
[x: string]: Animal // Numeric index type 'Animal' is not assignable to string index type 'Dog'.
[y: number]: Dog
}
/*
* 上边的例子很好的诠释了两种索引类型可以同时使用,但是这两者又必须
* 遵循之间的规则,那就是数字索引的返回值必须是字符串索引返回值类型的子类型
* 上边Animal并不是Dog的子类型,刚好弄反了,所以咱们在运行编译的时候会
* 报错。下面是正确的使用方式
* interface NotOkay {
* [x: string]: Animal
* [y: number]: Dog
* }
* 下面的例子是对类进行了约束
* */
interface Animal {
// 定义类的name属性值
name: string;
// 定义类中的方法
eat(name: string, gender: string): void
}
class Dog implements Animal {
name: string;
constructor(name: string){
this.name = name;
};
// 注意接口定义的方法有参数,当你不传也不会报错
eat() {
console.log("defind success")
}
}
var dog = new Dog("pika")
dog.eat()
class Cat implements Animal {
name: string;
constructor(name: string){
this.name = name;
};
eat(name: string, gender: string) {
console.log(`${this.name} is ${gender} cat like eat ${name}`)
}
}
var cat = new Cat("herry")
cat.eat("fish", "male")
/*
* 接口描述了类的公共部分,而不是私有跟公共两部分,他不会帮你检查类是够具有某些私有成员。
* 当一个类去实现一个接口的时候,他只会对其实例部分进行检查。constructor存在于类的静态部分,所以不再检查范围内。
*/
六、接口继承
- 和类一样,接口也可以相互继承。 这让我们能够从一个接口里复制成员到另一个接口里,可以更灵活地将接口分割到可重用的模块里。下面是实际应用的例子一起看一下:
interface Animal {
name: string
say(): void
}
interface Person extends Animal {
work(): void
closer: string
}
class Progremmer implements Person {
closer: string;
name: string;
say(): void {
console.log(`${this.name}说我喜欢穿${this.closer}`)
}
work(): void {
console.log(`${this.name}说工作使我快乐!!!`)
}
constructor(name: string, closer: string) {
this.name = name;
this.closer = closer;
}
}
let g:Person = new Progremmer("小明", "花衣服")
g.say();
g.work();
/*
* 上边中的接口继承了接口,就意味着person这个接口有了Animal的属性以及方法
* 这个时候咱们定义的程序员类去实现这个Person,实现这个person接口就意味着类必须实现
* 这个接口中的方法跟属性,上述例子有体现
*/
七、混合类型
- 接口能够描述 JavaScript 里丰富的类型。 因为 JavaScript 其动态灵活的特点,有时你会希望一个对象可以同时具有上面提到的多种类型。
interface Counter {
(start: number): string
name: string
say(str: string): void
}
/*
* 声明一个接口,如果只有(start: number): string一个成员,那么这个接口就是函数接口,
* 同时还具有其他两个成员,可以用来描述对象的属性和方法,这样就构成了一个混合接口。
*/
function myCounter(): Counter {
function counter(start: number): string {
return ""
}
/*
* function counter实现了接口的描述,成为了一个函数,因为myCounter是Counter类型* 的,所以counter还具有name属性跟say方法
*/
counter.name = "yxl"
counter.say = function (str: string) {
console.log(`我要学习${str}`)
}
let myCounters: Counter = counter
return myCounters
}
let s = myCounter();
s(10);
s.name= "sss";
s.say("TypeScript");
/*
* 官方文档这里使用了类型断言
* function counter(): Counter {
* let myCounters = (function (start: number) { }) as Counter
* myCounters.name = "yxl"
* myCounters.say = function (str: string) {
* console.log(`我要学习${str}`)
* }
* return myCounters
* }
*/
Interface(接口分享)第一节的更多相关文章
- 第一节 如何用Go实现单链表
一.概念介绍 下面这副图是我们单链表运煤车队. 每节运煤车就是单链表里的元素,每节车厢里的煤炭就是元素中保存的数据.前后车通过锁链相连,作为单链表运煤车,从1号车厢开始,每节车厢都知道后面拉着哪一节车 ...
- Ext JS学习第十六天 事件机制event(一) DotNet进阶系列(持续更新) 第一节:.Net版基于WebSocket的聊天室样例 第十五节:深入理解async和await的作用及各种适用场景和用法 第十五节:深入理解async和await的作用及各种适用场景和用法 前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G
code&monkey Ext JS学习第十六天 事件机制event(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ...
- 第一节:《线程安全和锁Synchronized概念》
第一节:线程安全和锁Synchronized概念 一.进程与线程的概念 (1)在传统的操作系统中,程序并不能独立运行,作为资源分配和独立运行的基本单位都是进程. 在未配置 OS 的系统中,程序的执行方 ...
- 我的第一节Android课
我的第一节安卓课程,今天非比寻常的一天,我开始了我程序猿之路的第一节安卓课程,安卓课程只是我的一个兴趣班,我的本专业是java开发,因为喜欢做一个属于自己的一个手机APP,就选多个一样技能,毕竟十八般 ...
- 第四章 跨平台图像显示库——SDL 第一节 与SDL第一次亲密接触
http://blog.csdn.net/visioncat/article/details/1596576 GCC for Win32 开发环境介绍(5) 第四章 跨平台图像显示库——SDL 第一节 ...
- seajs第一节,seajs基本使用
什么是seajs,它是干什么使用的,可以去网上搜索一下, 官网:http://seajs.org/docs/ 基本使用seajs <!DOCTYPE html> <html> ...
- VUE2.0实现购物车和地址选配功能学习第一节(来源--慕课网河畔一角)
第一节 vue知识 vue-resource:和后台交互的一个插件,实现get.post和jsonp等功能.(替代jQuery) vue特点: 1.易用:通过创建vue实例,{{}}绑定数据十分方便 ...
- go interface接口
一:接口概要 接口是一种重要的类型,他是一组确定的方法集合. 一个接口变量可以存储任何实现了接口方法的具体值.一个重要的例子就是io.Reader和io.Writer type Reader inte ...
- 第一节:.Net版基于WebSocket的聊天室样例
一. 说在前面的话 该篇文章为实时通讯系列的第一节,基于WebSocket编写了一个简易版聊天样例,主要作用是为引出后面SignalR系列的用法及其强大方便之处,通过这个样例与后续的SignalR对比 ...
- 第一节:ASP.NET开发环境配置
第一节:ASP.NET开发环境配置 什么是ASP.NET,学这个可以做什么,学习这些有什么内容? ASP.NET是微软公司推出的WEB开发技术. 2002年,推出第一个版本,先后推出ASP.NET2. ...
随机推荐
- es使用--新建、删除、增删改数据
# 进入bin目录 cd /czz/elsearch/bin # 后台启动(不加-d参数则是前台启动,日志在控制台) # 后台启动日志如果不配置,在es目录的logs下面 ./elasticsearc ...
- ARM-Linux S5PV210 UART驱动(转)
ARM-Linux S5PV210 UART驱动(3)----串口核心层.关键结构体.接口关系 尽管一个特定的UART设备驱动完全可以按照tty驱动的设计方法来设计,即定义tty_driver并实现t ...
- oracle 查询当前数据库环境
select SYS_CONTEXT('USERENV','AUTHENTICATION_TYPE')用户的认证类型 from dual;--用户的认证类型select SYS_CONTEXT('US ...
- 例题3-3 回文词(Palindromes, UVa401)
输入一个字符串,判断它是否为回文串以及镜像串.输入字符串保证不含数字0.所谓 回文串,就是反转以后和原串相同,如abba和madam.所有镜像串,就是左右镜像之后和原串相同,如2S和3AIAE.注意, ...
- CentOS 7操作系统基础优化介绍
01 前言 操作系统部署完毕后,需要做一些基础的简单优化操作,可以为系统未来的使用过程带来更多便捷. 02 操作系统安全优化配置 系统安装完毕后,默认系统中会存在两个重要的安全服务程序,建议将其首先进 ...
- PHP获取当前毫秒级别时间戳
PHP提供了一个microtime()函数,调用时不带可选参数,本函数以"msec sec"的格式返回一个字符串,其中 sec 是自 Unix 纪元(0:00:00 January ...
- phpexcel导出数据 出现Formula Error的解决方案
phpexcel导出数据报错 Uncaught exception 'Exception' with message 'Sheet1!A1364 -> Formula Error: Unexpe ...
- 【Azure Redis 缓存 Azure Cache For Redis】在创建高级层Redis(P1)集成虚拟网络(VNET)后,如何测试VNET中资源如何成功访问及配置白名单的效果
当使用Azure Redis高级版时候,为了能更好的保护Redis的安全,启用了虚拟网路,把Redis集成在Azure中的虚拟网络,只能通过虚拟网络VENT中的资源进行访问,而公网是不可以访问的.但是 ...
- Anderson《空气动力学基础》5th读书笔记 第2记——流体静力学初步
与物体在水中受到水的浮力一样,空气中的物体也会受到空气的浮力,但由于这个浮力往往比较小,实际中的很多问题我们常常将它忽略,而对于像热气球这样的靠空气的浮力产生升力的飞行器来说,空气的浮力是不能忽略的. ...
- B树摘要
BTree 以下内容是根据<算法导论>摘要而来,由于国内书籍对B树的定义是以阶来定义,而<算法导论>中使用的是最小度来定义,并且节点中关键字个数也不相同,在翻看网上博客时,产生 ...