typescript学习回顾(五)

今天来分享一下ts的泛型,最后来做一个练习

泛型

有时候,我们在书写某些函数的时候,会丢失一些类型信息,比如我下面有一个例子,我想提取一个数组的某个索引之前的所有数据

function getArraySomeData(newArr, n:number) {let newArr2:any[] = [];newArr.forEach((it, i) => {if (n > i) {newArr2.push(it);}});return newArr2;
}const arr = getArraySomeData(['1112', '1213', '121'], 2);
console.log(arr)

但是这个数组它可以是任意类型的,可以是对象,字符串,数字数组,这个时候不约束的话会存在ts的隐患,这个时候就有了泛型的概念。

概念

泛型的一个概念:

泛型相当于是一个类型变量,在定义时,无法预先知道具体的类型,可以用该变量来代替,只有在调用时,才能确定它的类型

很多时候,TS会智能的根据传递的参数,推导出泛型的具体类型

我们可以把刚才的代码使用泛型改成这种形式

function getArraySomeData<T>(newArr:T[], n:number) {let newArr2:T[] = [];newArr.forEach((it, i) => {if (n > i) {newArr2.push(it);}});return newArr2;
}const arr = getArraySomeData(['1112', '1213', '121'], 2);
console.log(arr)

如果没有传递具体类型,无法完成推导,默认是空对象。

进行传值

如果我 传递值只有ts会根据传递的类型进行严格类型检查,如下图,传递的是number,传递的就必须都是number

在这里插入图片描述

泛型设置默认值
function getArraySomeData<T = number>(newArr:any[], n:number) {}
在类型别名、接口、类使用泛型

回调函数,判断数组的某一项是否满足条件,这个某一项可以用泛型来代替

类型别名

type callback<T> = (n:T,i:number) => boolean;

接口

下面手动写了一个筛选的filter函数

interface callback<T> = (n:T,i:number) => boolean;function filter<T>(arr: T[], callback: callback<T>): T[] {const newArr: T[] = [];arr.forEach((n, i) => {if (callback(n, i)) {newArr.push(n);}});return newArr;
}

下面这个例子是一个数组帮助类,通过在类最外面设置了泛型T,来约束里面所有的方法的泛型,之后传递的所有的参数泛型以及数组放行,都是传递的值。

export class ArrayHelper<T> {constructor(private arr:T[]){}take(n: number): T[] {if (n >= this.arr.length) {return this.arr;}const newArr: T[] = [];for (let i = 0; i < n; i++) {newArr.push(this.arr[i])}return newArr;}shuffle() {for (let i = 0; i < this.arr.length; i++) {const targetIndex = this.getRandom(0, this.arr.length);const temp = this.arr[i];this.arr[i] = this.arr[targetIndex];this.arr[targetIndex] = temp;}}private getRandom(min: number, max: number) {const dec = max - min;return Math.floor(Math.random() * dec + min)}
}
泛型约束

这个是在有些特定场景的时候会需要使用,这里举一个简单的例子,我传递一个对象,然后我需要把这个对象的时间戳转换成日期字符串的形式

function dateFormat<T>(obj:T):T{obj.time = util.timeFormat(obj.time);return obj;
}

这个时候,ts会智能报错,报错的位置是obj.time的位置,因为泛型可以传递的类型是任意的类型,所以我用对象属性的方式,ts会进行报错,所以这种情况需要类型的约束

具体怎么做呢,很简单

interface hasTimePro{time : number
}function dateFormat<T extends hasTimePro>(obj:T):T{obj.time = util.timeFormat(obj.time);return obj;
}

上面通过接口定义要约束的泛型的类型,可以是对象,也可以是其他。然后在泛型里进行继承,继承这个接口,这样就可以对这个泛型进行一个约束。

多泛型

在很多情况下,我们可能参数特别多,要限制的类和接口可能不止一个,所以ts同样支持可以有多个泛型,具体的使用例子

我希望混合两个 数组,数组1和数组2,两个可能都是不一样的数组,但是两个数组长度必须一样,至于传递什么类型不管,只负责混合。这里就可以通过英文逗号将泛型隔开,然后设置多个泛型

function mixinArray<T, K>(arr1: T[], arr2: K[]): (T | K)[] {if (arr1.length !== arr2.length) {throw new Error('两个数组长度不等');}let result: (T | K)[] = [];for (let i = 0; i < arr1.length; i++) {result.push(arr1[i]);result.push(arr2[i]);}return result;
}const result = mixinArray([1, 3, 4], ["a", "b", "c"]);result.forEach(r => console.log(r));
小练习
开发一个字典类(Dictionary),字典里会保存键值对的数据键值对数据的特点:
- 键(key)可以是任何类型,但不允许重复
- 值(value)可以是任何类型
- 每一个键对应一个值
- 所有的键类型相同,所有的值类型相同字典类对键值对数组的操作:- 添加一个键值对
- 按照键删除对应的键值对
- 循环每一个键值对
- 得到当前键值对的数量
- 判断某个键是否存在
- 重新设置某个键的值,如果不存在,就添加
代码
  • src

    • dictionary.ts
    export type CallBack<K, V> = (key: K, val: V) => voidexport class Dictonary<K, V> {private keys: K[] = [];private vals: V[] = [];get size() {return this.keys.length;}set(key: K, val: V) {const i = this.keys.indexOf(key)if (i < 0) {this.keys.push(key);this.vals.push(val);} else {this.vals[i] = val;}}forEach(callback: CallBack<K, V>) {this.keys.forEach((k, i) => {const v = this.vals[i];callback(k, v);});}has(key: K) {return this.keys.includes(key);}delete(key: K) {const i = this.keys.indexOf(key);if (i === -1) {return;}this.keys.splice(i, 1);this.vals.splice(i, 1);}
    }
    
    • index.ts
    import { Dictonary } from "./dictionary";const dic = new Dictonary<string, number>();dic.set('a', 1);
    dic.set('b', 1);
    dic.set('a', 12);
    dic.set('c', 1231);dic.forEach((d,i)=>{console.log(`key:${d},v:${i}`)
    });dic.delete('b');dic.forEach((d,i)=>{console.log(`key:${d},v:${i}`)
    });console.log('当前键值对的数量:' + dic.size)
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/39042.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVM原理(十):JVM虚拟机调优分析与实战

1. 大内存硬件上的程序部署策略 这是笔者很久之前处理过的一个案例&#xff0c;但今天仍然具有代表性。一个15万PV/日左右的在线文档类型网站最近更换了硬件系统&#xff0c;服务器的硬件为四路志强处理器、16GB物理内存&#xff0c;操作系统为64位CentOS5.4&#xff0c;Resin…

js数组方法归纳——concat、join、reverse

1、concat( ) 用途&#xff1a;可以连接两个或多个数组&#xff0c;并将新的数组返回该方法不会对原数组产生影响 var arr ["孙悟空","猪八戒","沙和尚"];var arr2 ["白骨精","玉兔精","蜘蛛精"];var arr3 [&…

Vue Router的深度解析

引言 在现代Web应用开发中&#xff0c;客户端路由已成为实现流畅用户体验的关键技术。与传统的服务器端路由不同&#xff0c;客户端路由通过JavaScript在浏览器中控制页面内容的更新&#xff0c;避免了页面的全量刷新。Vue Router作为Vue.js官方的路由解决方案&#xff0c;以其…

阿里云centos 取消硬盘挂载并重建数据盘信息再次挂载

一、取消挂载 umount [挂载点或设备] 如果要取消挂载/dev/sdb1分区&#xff0c;可以使用以下命令&#xff1a; umount /dev/sdb1 如果要取消挂载在/mnt/mydisk的挂载点&#xff0c;可以使用以下命令&#xff1a; umount /mnt/mydisk 如果设备正忙&#xff0c;无法立即取消…

【Spring Boot】简单了解spring boot支持的三种服务器

Tomcat 概述&#xff1a;Tomcat 是 Apache 软件基金会&#xff08;Apache Software Foundation&#xff09;的 Jakarta EE 项目中的一个核心项目&#xff0c;由 Apache、Sun 和其他一些公司及个人共同开发而成。它作为 Java Servlet、JSP、JavaServer Pages Expression Languag…

系统安全及应用(命令)

目录 一、账号安全控制 1.1 系统账号清理 1.2 密码安全控制 1.3 历史记录控制 1.4 终端自动注销 二、系统引导和登陆控制 2.1 限制su命令用户 2.2 PAM安全认证 示例一&#xff1a;通过pam 模块来防止暴力破解ssh 2.3 sudo机制提升权限 2.3.1 sudo命令&#xff08;ro…

Java的日期类常用方法

Java_Date 第一代日期类 获取当前时间 Date date new Date(); System.out.printf("当前时间" date); 格式化时间信息 SimpleDateFormat simpleDateFormat new SimpleDateFormat("yyyy-mm-dd hh:mm:ss E); System.out.printf("格式化后时间" si…

【windows|012】光猫、路由器、交换机详解

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 ​ &#x1f3c5;阿里云ACE认证高级工程师 ​ &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社…

windows USB 驱动开发-URB结构

通用串行总线 (USB) 客户端驱动程序无法直接与其设备通信。 相反&#xff0c;客户端驱动程序会创建请求并将其提交到 USB 驱动程序堆栈进行处理。 在每个请求中&#xff0c;客户端驱动程序提供一个可变长度的数据结构&#xff0c;称为 USB 请求块 (URB) &#xff0c;URB 结构描…

ctfshow-web入门-命令执行(web75-web77)

目录 1、web75 2、web76 3、web77 1、web75 使用 glob 协议绕过 open_basedir&#xff0c;读取根目录下的文件&#xff0c;payload&#xff1a; c?><?php $anew DirectoryIterator("glob:///*"); foreach($a as $f) {echo($f->__toString(). ); } ex…

读书笔记-Java并发编程的艺术-第3章(Java内存模型)-第9节(Java内存模型综述)

3.9 Java内存模型综述 前面对Java内存模型的基础知识和内存模型的具体实现进行了说明。下面对Java内存模型的相关知识做一个总结。 3.9.1 处理器的内存模型 顺序一致性内存模型是一个理论参考模型&#xff0c;JMM和处理器内存模型在设计时通常会以顺序一致性内存模型为参照。…

ORB-SLAM2 安装编译运行(非 ROS)

安装编译 必备安装工具 主要包括 cmake 、 git 、 gcc 、 g gcc 的全称是 GNU Compiler Collection&#xff0c;它是由 GNU 推出的一款功能强大的、性能优越的 多平台编译器&#xff0c;是一个能够编译多种语言的编译器。最开始 gcc 是作为 C 语言的编译器&#xff08;GNU …

如何将等保2.0的要求融入日常安全运维实践中?

等保2.0的基本要求 等保2.0是中国网络安全领域的基本国策和基本制度&#xff0c;它要求网络运营商按照网络安全等级保护制度的要求&#xff0c;履行相关的安全保护义务。等保2.0的实施得到了《中华人民共和国网络安全法》等法律法规的支持&#xff0c;要求相关行业和单位必须按…

C#/WPF 自制白板工具

随着电子屏幕技术的发展&#xff0c;普通的黑板已不再适用现在的教学和演示环境&#xff0c;电子白板应运而生。本篇使用WPF开发了一个电子白板工具&#xff0c;功能丰富&#xff0c;非常使用日常免费使用&#xff0c;或者进行再次开发。 示例代码如下&#xff1a; Stack<St…

拓扑排序[讲课留档]

拓扑排序 拓扑排序要解决的问题是给一个有向无环图的所有节点排序。 即在 A O E AOE AOE网中找关键路径。 前置芝士&#xff01; 有向图&#xff1a;有向图中的每一个边都是有向边&#xff0c;即其中的每一个元素都是有序二元组。在一条有向边 ( u , v ) (u,v) (u,v)中&…

JavaScript 动态网页实例 —— 广告效果

广告是现代网页设计中不可或缺的内容。广告可以有很多种形式,但最终目的都是要吸引观众的注意力。尽管广告少不了画面、音效和广告语等效果,但其实现主要还是应用JavaScript 代码,只要很好掌握了JavaScript程序设计,剩下的就是创意和美工了。本章介绍几种广告效果,包括对联…

ChatGPT 官方发布桌面端,向所有用户免费开放

Open AI 官方已经发布了适用于 macOS 的 ChatGPT 桌面端应用。 此前&#xff0c;该应用一直处于测试阶段&#xff0c;仅 Plus 付费订阅用户可以使用。 目前已面向所有用户开放&#xff0c;所有 Mac 用户均可免费下载使用。 我们可以访问官网下载安装包&#xff1a;https://op…

Java利用poi实现word,excel,ppt,pdf等各类型文档密码检测

介绍 最近工作上需要对word,excel,ppt,pdf等各类型文档密码检测&#xff0c;对文件进行分类&#xff0c;有密码的和没密码的做区分。查了一堆资料和GPT都不是很满意&#xff0c;最后东拼西凑搞了个相对全面的检测工具代码类&#xff0c;希望能给需要的人带来帮助。 说明 这段…

PHP 爬虫之使用 Curl库抓取淘宝商品列表数据网页的方法

使用 PHP 的 cURL 库来抓取淘宝商品列表数据网页需要谨慎&#xff0c;因为淘宝等电商平台通常会有反爬虫机制&#xff0c;以防止数据被滥用。然而&#xff0c;如果你只是出于学习目的&#xff0c;并且了解并遵守了淘宝的robots.txt文件和相关的使用条款&#xff0c;你可以尝试使…

2024 年江西省研究生数学建模竞赛题目 B题投标中的竞争策略问题--完整思路、代码结果分享(仅供学习)

招投标问题是企业运营过程中必须面对的基本问题之一。现有的招投标平台有国家级的&#xff0c;也有地方性的。在招投标过程中&#xff0c;企业需要全面了解招标公告中的相关信息&#xff0c;在遵守招投标各种规范和制度的基础上&#xff0c;选择有效的竞争策略和技巧&#xff0…