《三》大话 Typescript 接口
> 前言: 本文章为 TypeScript 系列文章. 旨在利用碎片时间快速入门 Typescript. 或重新温故 Typescript 查漏补缺.在官方 api 的基础上, 加上一些日常使用的感想. 如果感兴趣的话~ 欢迎关注, 后续持续推出文章.
文章列表:
- 《一》大话 TypeScript 基本类型
- 《二》大话 Typescript 枚举
- 《三》大话 Typescript 接口
- 《四》大话 Typescript 泛型
- 《五》大话 Typescript 函数
- 《六》大话 Typescript 类
- 《七》大话 Typescript react 类
- 《八》大话 Typescript react 函数
- ……
目录结构:
- 接口对象的基本属性
- 接口声明方式
- 可索引类型接口
- 接口继承接口
- 接口实现
接口类型是一个非常强大的类型定义,是在日常代码中经常会使用到的的一个功能. 系统的了解他非常的重要.
#### 接口对象的基本属性
接口对象的属性有正常属性, 可选属性, 只读属性 , 如下代码:
```
interface List {
readonly id: number; // 不可修改, 只可读取
name?: string; // 可以有, 可以没有
data: string; // 一定要有
eat(): void; // 也可以声明一个函数
}
let a: List = {
id: 1,
data: 'msg'
}
a.id = 2;
// 报错: Cannot assign to 'id' because it is a constant or a read-only property.
let b: List = {
id: 1
}
// Type '{ id: number; }' is not assignable to type 'List'.
// Property 'data' is missing in type '{ id: number; }'.
// 报错: 缺少 data 属性
```
#### 接口声明方式
接口的声明和使用方式特别简单, 回顾第一篇文章的声明方式.
(变量/函数): type // [type 为上面的数据类型 ]
这个 type 可以是普通的类型, 也可以是一个 interface 接口, 大概有以下三种使用方式. 如下:
```
interface List {
data: string;
}
// 声明一个对象
let obj: List = {data: 'msg'}
// 函数声明参数, 返回值
function a (x: List):List {
return x;
}
// 类实现接口, 类似于 java 语言, 在接口描述一个方法,在类里实现它
// 这种方式一般很少使用他, 不过可以了解一下
class Crazy implements List {
constructor() {}
data: string;
}
```
日常使用我们经常会有一些嵌套对象, 比如拿到后台接口的格式是这样子的.
```
let res = {
subject: 'math',
detail:[{
id: 1,
data: '数学'
}]
}
```
interface 是一个很灵活的属性. 可以多层嵌套.我们可以用下面的方式来定义,
```
interface List {
id: number;
data: string;
}
interface LearnList {
subject: string,
detail: List[];
}
let res: LearnList = {
subject: 'math',
detail: [{
id: 1,
data: '数学'
}]
}
```
如果作为函数参数声明的话, 会有一个有意思的地方. 我们直接传值的话, 会有报错提示. 那如何解决这个报错提示? 在不修改 interface 声明的情况 ?
```
function transformData(data: LearnList) {
return data;
}
transformData({
subject: 'math',
xxx: 'sss', //报错, 多了一个属性
detail: [{
id: 1,
data: '数学'
}]
})
```
解决方法:
1. 将值赋值给一个对象.
这里涉及到一个类型兼容性, 后面的文章会详细讲. 此处大概讲一下. 也就是 cache 他有 LearnList 声明的对象里面的所有属性, 那 cache 兼容 LearnList 声明的对象, cache 也就可以赋值给 LearnList声明的对象.
```
const cache = {
subject: 'math',
xxx: 'sss', //报错, 多了一个属性
detail: [{
id: 1,
data: '数学'
}]
};
transformData(cache) //不报错
```
2. 类型断言
这个特性也经常会使用, 学起来. 直接到传的参数后面调用 as LearnList, 告诉编辑器, 我们明确知道这个对象是 LearnList 的,请绕过这个检查.
```
transformData({
subject: 'math',
xxx: 'sss',
detail: [{
id: 1,
data: '数学'
}]
} as LearnList )
```
3. 字符串索引签名.
看下面
#### 可索引类型接口
从上面的问题看出, 在原有的对象声明中多一个属性就报错了. 有些场景我们可能对入参的参数比较灵活, 除了我们规定的一些参数, 不确定还会传其他什么参数进来的时候, 可以使用 “可索引类型接口”
```
interface List {
id: number;
data: string;
}
interface LearnList {
subject: string,
detail: List[];
[x: string]: any; // 可以用任意的string类型去索引声明的对象, 值是any类型
}
transformData({
subject: 'math',
xxx: 'sss',
detail: [{
id: 1,
data: '数学'
}]
})
```
这样也可以解决上面的问题. 下面来简单梳理下 可索引类型接口.
1. 用字符串索引的接口
```
interface StringArray {
[x: string]: string; // 表示可以用任意字符串去索引 对象, 得到一个字符串的值
}
```
2. 用数字索引的接口
```
interface StringArray {
[x: number]: string; // 用任意的 number 去索引对象, 都会得到一个 string 类型. 其实就是我们的数组了
}
```
3. 混用2种索引
```
interface StringArray {
[x: string]: string;
[z: number]: string;
}
let x: StringArray = {
1: '2323',
'2':'23423'
} // 既可以用字符串索引也可以用数字索引
```
注意点: 不管是数字索引还是字符串索引, 下面的索引值类型, 必须是上面索引的 子类型. 因为我们已经规定了任意的索引得到的值都是 string , 此时任何一个成员的值变成 number 都会报错.
```
interface StringArray {
[x: string]: string;
[z: number]: string;
y: 22; //报错 : Property 'y' of type '22' is not assignable to string index type 'string'
}
interface StringArray {
[x: string]: string;
[z: number]: number; //报错 因为 string 不兼容 number
}
interface StringArray {
[x: string]: any;
[z: number]: number; //正常· any 兼容 number
}
```
#### 接口继承接口
跟类的继承语法是一样的. 直接看代码
```
interface Point {
x: number;
}
// 继承一个接口直接 extends
interface Draw extends Point {
y: number;
}
interface Shape {
draw(): void;
}
//继承多个接口用逗号 , 隔开
//同样的,他可以被反复 extends
interface Human extends Draw, Shape { }
// 必须具有继承接口的所有属性
let peen: Human = {
x: 1,
y: 1,
draw: () => { },
}
```
#### 接口实现
这一块其实是相对于 javascript 而言, 引入了 java 的一些属性. 比如 implements. 这一块在实际项目中其实很少用到. 但还是简单讲一下.
注意点:
1. 接口只能描述类的公共部分,不能描述私有成员
```
interface Point {
x: number;
draw(): void;
}
class Draw implements Point {
constructor() {
}
private x: number; //报错 Class 'Draw' incorrectly implements interface 'Point'. Property 'x' is private in type 'Draw' but not in type 'Point'.
draw() { }
}
```
2. 类实现接口时 ,必须实现接口中所有的属性
```
interface Point {
x: number;
draw(): void;
}
class Draw implements Point {
constructor() {
}
x: number;
draw() { } // 如果这行不见了,就会报错
}
```
3. 接口无法约束类的构造函数
```
interface Point {
x: number;
draw(): void;
new(x: number): void; // 报错. 不用写这个
}
class Draw implements Point {
constructor(x: number) {
this.x = x;
}
x: number;
draw() { }
}
```
#### 总结
这篇文章主要是列举了 interface 的一些常见用法. 其实在实际运用中, 我们会用更方便的方式去使用他, 比如 Partial<interface> 全部让参数变成可选, 或者使用交叉类型联合类型让 interface 更加灵活. 秉承着一篇文章不能太长的原则. 今天就到这里结束了. 感兴趣可以关注我~ 长期连载
最后
欢迎关注「前端加加」,认真学前端,做个有专业的技术人...
《三》大话 Typescript 接口的更多相关文章
- typescript接口的概念 以及属性类型接口
/* 1.vscode配置自动编译 1.第一步 tsc --inti 生成tsconfig.json 改 "outDir": "./js", 2.第二步 任务 ...
- TypeScript入门三:TypeScript函数类型
TypeScript函数类型 TypeScript函数的参数 TypeScript函数的this与箭头函数 TypeScript函数重载 一.TypeScript函数类型 在上一篇博客中已经对声明Ty ...
- 从C#到TypeScript - 接口
总目录 从C#到TypeScript - 类型 从C#到TypeScript - 高级类型 从C#到TypeScript - 变量 从C#到TypeScript - 接口 从C#到TypeScript ...
- VGA、DVI、HDMI三种视频信号接口
目前,电脑显示器常见的接口主要有HDMI.DP.DVI.VGA等4种接口.显示器数据线性能排名:DP>HDMI>DVI>VGA.其中 VGA是模拟信号,已经被主流所淘汰,DVI.H ...
- C# 语法三 抽象类和接口
1.抽象类 2.接口 一 抽象类 跟普通类的区别: a)用abstract标识类.抽象方法 b)抽象方法,只能声明,不能定义 c)抽象类不能实例化 二 接口 接口用interface标识,所有的成员( ...
- 创建执行线程方式三:实现Callable接口
Callable接口 ① Java 5.0 在 java.util.concurrent 提供了一个新的创建执行 线程的方式:Callable 接口② Callable 接口类似于 Runnable, ...
- TypeScript接口与类的使用
一.TypeScript接口 Interfaces 可以约定一个对象的结构 一个对象去实现一个接口 就必须拥有这个接口中所有的成员用interface定义接口, 并且定义接口中成员的类型 编译之后会发 ...
- Hi3559AV100外接UVC/MJPEG相机实时采图设计(三):V4L2接口通过MPP平台输出
可以首先参考前面两篇文章: Hi3559AV100外接UVC/MJPEG相机实时采图设计(一):Linux USB摄像头驱动分析: https://www.cnblogs.com/iFrank/p/1 ...
- typescript接口---interface
假如我现在需要批量生产一批对象,这些对象有相同的属性,并且对应属性值的数据类型一致.该怎么去做? 在ts中,因为要检验数据类型,所以必须对每个变量进行规范,自然也提供了一种批量规范的功能.这个功能就是 ...
随机推荐
- 洛谷p2330繁忙的都市题解
题面 根据题意来分析, 要求出你选了几条路, 最小生成树是能解的, 那么就直接输出n - 1条路即可, 至于最大值则走一遍最小生成树求出即可 这里提供最小生成树的两种方法 1. 克鲁斯卡尔 克鲁斯卡尔 ...
- 使用VS2017遇到的一些小问题
一.去掉预编译头 使用VS2017的时候,发现总是会有"pch.h","stdafx.h"这类预编译头,去掉还会报错.作为新手的我,暂时用不到这些预编译头,于是 ...
- kali linux 局域网攻击(一)
一.攻击准备 此为局域网攻击测试 1)查看自己的IP地址,记住默认网关 2)扫描局域网中的IP fping -asg nbtscan -r 网关地址/ 3)使用arpspoof进行断网攻击 攻击前, ...
- FZU Monthly-201905 获奖名单
FZU Monthly-201905 获奖名单 冠军: 郑学贵 S031702338 一等奖: 林闽沪 S131700309 罗继鸿 S031702524 二等奖: 苏锦程 S031802325 林鑫 ...
- sql server查看表大小
查看SqlServer 数据库中各个表多少行 : SELECT A.NAME ,B.ROWS FROM sysobjects A JOIN sysindexes B ON A.id = B.id WH ...
- 剑指offer:数据流中的中位数
题目描述: 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值.我 ...
- 颜色空间模型(HSV\LAB\RGB\CMYK)
通过Photoshop的拾色器,我们知道表征颜色的模型的不止一种,本文将系统并且详细讨论这四种模型(HSV.LAB.RGB和CMYK)之间的联系以及应用.本文部分章节整合了多位优秀博主的博客(链接见本 ...
- Research Guide: Pruning Techniques for Neural Networks
Research Guide: Pruning Techniques for Neural Networks 2019-11-15 20:16:54 Original: https://heartbe ...
- 虚拟环境上的jupyterhub开机启动设置
为了让jupyterhub 开机启动,或者以服务的方式启动,折腾了好久.环境 ubuntu 16.04anaconda >= 4.5python35 jupyterhub 0.9.4node 6 ...
- JAVA | Java对象的内存分配过程是如何保证线程安全的?
JAVA | Java对象的内存分配过程是如何保证线程安全的? 专注于Java领域优质技术,欢迎关注 作者 l Hollis 来源 l Hollis(ID:hollischuang) JVM内存结构, ...