typescript基础篇(3):接口
3. 接口
关于接口,你可以理解为定义了属性和类型,但是没有定义其它任何东西的构造函数。接口可以用来约束对象,函数乃至代码结构。
3.1 接口的使用
如果你和后端同事正在联调,讨论好的数据类型是这样的:
[{id:1,name:'djtao'},{id:2,name:'dangjingtao'}...]
试问,如何规范这样的一个接口呢?
interface List {
id: number
name: string
}
interface Result {
data: List[]
}
const render = (result: Result) => {
result.data.forEach((item) => {
console.log(item)
})
}
const result = {
data: [{ id: 1, name: "djtao" }, { id: 2, name: "dangjingtao" }],
}
render(result)
这里我们使用接口来描述一个拥有id和name字段的List对象。并且定义Result是由List组成的数组。那么,一个标准的接口就被定义出来了。
3.2 接口数据处理
如果后端给你的数据加了一个age字段:
const result = {
data: [{ id: 1, name: "djtao" }, { id: 2, name: "dangjingtao",age:31 }],
}
代码也不会报错。从这里体现了动态语言的特征(鸭子模型),只要满足接口的必要条件,就可以允许。
但是,如果:
render({
data: [{ id: 1, name: "djtao" }, { id: 2, name: "dangjingtao", age: 31 }],
})
这样又会报错。
这时候就需要类型断言。断言时,render的入参用Result类型s规范。如下两种都是等价的:
// 在react(tsx)中使用容易被混淆
render(<Result>{
data: [{ id: 1, name: "djtao" }, { id: 2, name: "dangjingtao", age: 31 }],
});
// tsx只能使用这种方式
render({
data: [{ id: 1, name: "djtao" }, { id: 2, name: "dangjingtao", age: 31 }],
} as Result)
你也可以使用字符串索引签名,在定义List时:
interface List {
id: number
name: string
[prop: string]: any // 允许接受其它属性
}
3.3 接口成员的特性
假设后端接口可能存在age属性,也可能不存在,前端需要根据此属性进行渲染——
interface List {
id: number
name: string
}
interface Result {
data: List[]
}
const render = (result: Result) => {
result.data.forEach((item) => {
console.log(item)
if (item.age) {// 报错
console.log(item.age)
}
})
}
const result = {
data: [{ id: 1, name: "djtao" }, { id: 2, name: "dangjingtao", age: 31 }],
}
render(result)
如果我给List定义了age,也不行(类型不兼容),这时候可以使用可选属性(加?)
interface List {
id: number
name: string
age?: number
}
这样就符合预期了。
因为id是重要属性,还可以对id设置只读属性(readonly)
interface List {
readonly id: number
name: string
age?: number
}
这时如果尝试修改id,就会报错。
上面的例子,属性个数都是确定的。如果是不确定的,可以使用索引属性。
比如:
interface StringArray {
[index: number]: string
}
let chars: StringArray = ["a", "b"]
表示声明了一个由字符串组成的数组。也可以混用:
interface StringArray {
[index: number]: string
[z: string]: string
}
3.4 用接口定义函数
回顾之前所学:在ts中定义一个函数可以是这样:
const add = (a: number, b: number) => a + b
用接口描述:一个函数,两个入参都是数字,返回的也是数字。
interface Add {
(x: number, y: number): number
}
// 或者
type Add = (x: number, y: number) => number
let add: Add = (a, b) => a + b
type和interface 多数情况下有相同的功能,就是定义类型。但有一些小区别:type:不是创建新的类型,只是为一个给定的类型起一个名字。type还可以进行联合、交叉等操作,引用起来更简洁。interface:创建新的类型,接口之间还可以继承、声明合并。如果可能,建议优先使用 interface。
接口也可以同时用做返回函数/字符串和数字:
interface Lib {
(): void
version: string
do(): void
}
// 这样实际上声明的是一个单例
// let lib: Lib = (() => {}) as Lib
// 考虑工厂模式 可以创建多个实例
const getLib = () => {
let lib: Lib = (() => {}) as Lib
lib.version = "1.0"
lib.do = () => {}
return lib
}
- 前端MVC Vue2学习总结(三)——模板语法、过滤器、计算属性、观察者、Class 与 Style 绑定
- 前端MVC Vue2学习总结(二)——Vue的实例、生命周期与Vue脚手架(vue-cli)
- hive具体操作
- hive中配置hwi
- 从零开始内网安全渗透学习
- hive启动后相关操作
- 开源API测试工具 Hitchhiker v0.10 - 中文版
- 强大的API测试工具Hitchhiker v0.9 基于UI的断言测试,回顾2017
- 开源API测试工具 Hitchhiker v0.8 - 自动化测试结果统计
- 开源API测试工具 Hitchhiker v0.7更新 - Schedule的对比diff
- com.mysql.jdbc.exceptions.jdbc4.CommunicationsE...
- 简陋的swift carthage copy-frameworks 辅助脚本
- 【自问自答】关于 Swift 的几个疑问
- 高级PHP应用程序漏洞审核技术【一】
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法