TypeSprict -- 接口

TS -- interface 接口

第一条的参考文章

1.了解什么是接口:接口只是定义了一些方法,而没有去实现,多用于程序
设计时,只是设计需要有什么样的功能,但是并没有实现任何功能,这些功
能需要被另一个类(B)继承后,由 类B去实现其中的某个功能或全部功能
'接口定义了多个类的公共行为规范,这些行为是和外部进行交流的通道'

2.疯狂java 讲义中描述接口(这里笔者稍微改动了下):电脑主板上有usb接
口,但是不同时期usb接口遵循不同的协议,必须遵循了这个协议才能享受
对应不同时期usb 版本带来的体验,这个规范我们可以理解成接口,他定义
了一些规则,但具体的方法我们实现这个接口的时候各大厂商按照自己优化
去实现,好处是让规范和实现分离,让软件之间面向接口耦合,是一种松耦
合的设计,这样主板就不会关心这个是那个厂家制造的usb,也不管你的内
部实现,只要你遵循了我的协议,我们就能匹配。'java' 还利用接口的特性
实现了多继承

3.pyhon 角度来看,pyhon没有明确接口概念,使用的抽象类来变相实现,
加上本身的多继承的特性,也让他可以将接口这个概念和其他语言划分开

4.上面是通过csdn作者--' leeyan85'和疯狂java讲义书中加上笔者本身略微
学习过pyhon 和 java,在这基础上通过语言的对比,和描述希望可以对前端
本神没有借口概念的开发一点帮助
复制代码

开始TS的接口

1.可选类型 -- 用'?'号修饰
2.索引签名 -- 可以添加不确定参数
3.限制接口中的参数是只读 -- readonly
4.接口 数组 和只读
5.接口定义函数
6.接口做闭包(混合类型)
7.绕过接口的多余参数检查-- 三种方式
复制代码

通过几个例子了解ts 接口

1.例子来自'官方文档',改进了解接口
2.下面的第一个案例是按照官网思路进行改进的为了更加直观,有一个 方法
用了打印个人信息的,我们用'ts' 约束了 传递参数,有几个分别是什么类型
3.看完下面的案例其实深入思考,可以指定传入的对象每一个key规定类
型,和传递参数,缺点灵活性不高,不能将公共格式参数的提取出来复用
复制代码
  • 根据官网案例的思路改进
// 这里用了ts规定了parmasinfo 参数格式
function printPesonInfo(parmasinfo:{name:string,sex:string}) {
    console.log(`姓名:${parmasinfo.name }性别:${parmasinfo.sex}`)
}
// 错误使用因为没有使用定义的sex
//  let paramsinfo = {name:'wang',age:12}

let paramsinfo = {name:'wang',age:12,sex:'男'} 
printPesonInfo(paramsinfo) // 姓名:wang性别:男
复制代码

了解接口 -- interface

1. 使用在变量前声明'interface'
2. 简单案例:
    声明一个interface:
    interface person {
        name: string;
        age: number;
    }
    然后就可以使用这个interface来限制一个对象的类型:
    let tom: person = {
        name: 'tom',
        age: 12
    }
3.和刚才比我们解决了缺点中的问题可以公共提取,规范一个系列
复制代码
  • 所有动物都有一个最基本的信息名字和性别,必须按照这个规范来创建
interface Baseinfo {
    name:string,
    sex:string
}
// 人 
function printPesonInfo(parmasinfo: Baseinfo) {
    console.log(`姓名:${parmasinfo.name }性别:${parmasinfo.sex}`)
}
// 动物
function printAnimalInfo(parmasinfo: Baseinfo) {
    console.log(`姓名:${parmasinfo.name }性别:${parmasinfo.sex}`)
}

let paramsinfo = {name:'wang',age:12,sex:'男'} 
printPesonInfo(paramsinfo) // 姓名:wang性别:男
let paramsAnimainfo = {name:'小黑',age:12,sex:'公'} 
printAnimalInfo(paramsAnimainfo) // 姓名:小黑性别:公
复制代码

可选类型 -- 用'?'号修饰

1.现在我们发现不是接口中提供的每一个参数我们都需要,为此'TS' 提供了
一种'?' 来修饰,被问号修饰的参数就是可以选传,不是必须参数
复制代码
interface Baseinfo {
    name:string,
    sex?:string
}
// 人 
function printPesonInfo(parmasinfo: Baseinfo) {
    console.log(`姓名:${parmasinfo.name }`)
}

let paramsinfo = {name:'wang'} 
printPesonInfo(paramsinfo) // 姓名:wang
复制代码

索引签名 -- 可以添加不确定参数

1.刚才的问号让我们可以选填一些参数,但是如果需要增加一些不确定
参数就需要使用 '索引签名'
2.利用这个可以规定你的索引签名的类型(即使你的索引规定是string类型
但也可以使用数字,案例三有说明)
3.主要注意这里有个问题:需要注意的是,一旦定义了任意属性,
那么确定属性和可选属性的类型都必须是它的类型的子集(案例二)
复制代码
  • 案例一
interface Baseinfo {
    name:string,
    sex?:string,
    [other:string]:any
}
// 人 
function printPesonInfo(parmasinfo: Baseinfo) {
    console.log(`姓名:${parmasinfo.name }`)
}

// 接口中的索引签名other 就会收到age
printPesonInfo( {name:'wang',age:13}) // wang
复制代码
  • 案例二的错误示范
// 错误示范
interface Person {
    name: string;
    age?: number; // 必须是string类型才行,因为给是propName类型的子集3
    [propName: string]: string; // 改正 [propName: string]: any;
}
}

复制代码
  • 案例三
interface Person {
    name: string;
    age?: number; // 必须是string类型才行,因为给是propName类型的子集3
    [propName: string]: any;
}

let tom: Person = {
    name: 'Tom',
    age: 25,
    1: 'male' // 因为key 会调用 自带的toString 方法
};

复制代码

限制接口中的参数是只读 -- readonly

1.readonly 和 const 都是只读,但两者如何用区别在哪里,首先'readonly ''TS' 在接口提出,只针对接口中的参数赋值后就禁止更改,而const 是
es6 提出的针对变量,不让变量进行更改
2.用'ts' 文档的总结来说:最简单判断该用readonly还是const的方法是看要
把它做为变量使用还是做为一个属性。 做为变量使用的话用const,若做
为属性则使用readonly复制代码
  • 使用
interface Point {
    readonly x: number;
    readonly y: number;
}
// p1 是接口Point 类型
let p1: Point = { x: 10, y: 20 };
p1.x = 5; // error! 已经设置了readonly 属性所以禁止更改
复制代码

接口 数组 和只读

1.我们还可以利用接口定义数组位置的类型,和元组不同,元组不仅限制
了类型也限制了最开始赋值时候的长度(push 还是可以往元组添加东西的)

复制代码
  • 接口定义数组
// 接口 数组 和只读
// 定义了一个数组接口,数组第一位必须数字,第二位是字符串
interface ArrInter {
    0:number,
    1:string
}

let arr: ArrInter = [1,"w",3]
console.log(arr)
复制代码
  • 接口 数组 和只读
// 定义了一个数组接口,数组第一位必须数字,第二位是字符串
interface ArrInter {
    readonly 0:number,
    1:string
}

let arr: ArrInter = [1,"w",3]
arr[0] = 5 // erro 后续禁止改变
复制代码

接口定义函数

1.接口不止能定义变量值也可以定义函数
复制代码
  • 将BaseInfo 加工
//  定义了一个信息接口,里面有姓名,年龄和一个吃的方法返回的类型是string类型
interface BaseInfo{
    name:string,
    age:number,
    eat(food: string):string
}
const personInfo:BaseInfo = {
    name:'wang',
    age:99,
    eat(parmas){
        return parmas
    }
}
复制代码
  • 只定义 方法的接口
1.对于函数类型的类型检查来说,函数的参数名不需要与接口里定义的名字相匹配
2.函数的参数会逐个进行检查,要求对应位置上的参数类型是兼容的
复制代码
interface SearchFunc {
  (source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function(src: string, sub: string): boolean {
  let result = src.search(sub);
  return result > -1;
}
复制代码
  • 类型别名
// 箭头函数不加大括号的含义是 返回 省略了return
type PersonInfo = (name:string) => string

let personName:PersonInfo = (name) => name 
复制代码

接口做闭包(混合类型)

1.后期深入 现在没懂
复制代码
  • 有时候,一个函数还可以有自己的属性和方法:
interface Counter {
    (start: number): string;
    interval: number;
    reset(): void;
}

function getCounter(): Counter {
    let counter = <Counter>function (start: number) { };
    counter.interval = 123;
    counter.reset = function () { };
    return counter;
}

let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;
复制代码
  • 编译后效果
function getCounter() {
    var counter = function (start) { };
    counter.interval = 123;
    counter.reset = function () { };
    return counter;
}
var c = getCounter();
c(10);
c.reset();
c.interval = 5.0;
复制代码
  • 案例二 编译前
interface Counter {
    (): void;
    count: number;
}

function getCounter(): Counter {
    const c = ()=>{
        c.count++
    }
    c.count = 0
    return c
}
复制代码
  • 编译后
function getCounter() {
    var c = function () {
        c.count++;
    };
    c.count = 0;
    return c;
}
复制代码

绕过接口的多余参数检查-- 三种方式

  • 什么是接口的多余参数检查
interface Baseinfo {
    name:string,
    sex?:string
}
// 人 
function printPesonInfo(parmasinfo: Baseinfo) {
    console.log(`姓名:${parmasinfo.name }`)
}

// 如果直接传递参数,且传递的参数key未在接口中定义会提示错误
printPesonInfo( {name:'wang',age:13} ) // 报错的
复制代码
  • 第一种解决使用类型断言
interface Baseinfo {
    name:string,
    sex?:string
}
// 人 
function printPesonInfo(parmasinfo: Baseinfo) {
    console.log(`姓名:${parmasinfo.name }`)
}

// 利用类型断言,告诉编译器我们传递的参数 就是Baseinfo 接口的东西
printPesonInfo( {name:'wang',age:13} as Baseinfo ) // wang
复制代码
  • 第二种 索引签名
interface Baseinfo {
    name:string,
    sex?:string,
    [other:string]:any
}
// 人 
function printPesonInfo(parmasinfo: Baseinfo) {
    console.log(`姓名:${parmasinfo.name }`)
}

// 接口中的索引签名other 就会收到age
printPesonInfo( {name:'wang',age:13}) // wang
复制代码
  • 利用类型兼容性
interface Baseinfo {
    name:string,
    sex?:string,
}
// 人 
function printPesonInfo(parmasinfo: Baseinfo) {
    console.log(`姓名:${parmasinfo.name }`)
}

let paramsinfo = {name:'wang',age:13} 
// 类型兼容性就是我们定义的paramsinfo 不管有都少东西,只要包含接口中定义的即可
printPesonInfo(paramsinfo) // 姓名:wang
复制代码
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值