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) => void
    
    export 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)
    

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mouse Prealbumin ELISA Kit小鼠前白蛋白ELISA试剂盒

前白蛋白&#xff08;PRE&#xff09;是一种由4条相同的多肽链组成的四聚体蛋白。电泳时&#xff0c;它比血清白蛋白的迁移速度更快&#xff0c;PRE可以作为多种疾病患者营养评价的标志物。ICL的Mouse Prealbumin ELISA Kit应用双抗体夹心法测定小鼠样本中前白蛋白水平&#xf…

CentOS7源码安装nginx并编写服务脚本

华子目录 准备下载nginx源码包关闭防火墙关闭selinux安装依赖环境 解压编译安装测试编写服务脚本&#xff0c;通过systemctl实现服务启动与关闭测试 准备 下载nginx源码包 在源码安装前&#xff0c;我们得先下载nginx源码包https://nginx.org/download/这里我下载的是nginx-1…

《梦醒蝶飞:释放Excel函数与公式的力量》8.2 COUNTA函数

8.2 COUNTA函数 COUNTA函数是Excel中用于统计指定区域内所有非空单元格数量的函数。它能够统计数值、文本、错误值以及公式返回的结果&#xff0c;是数据分析中常用的统计工具。 8.2.1 函数简介 COUNTA函数用于统计指定区域中所有非空单元格的数量。它与COUNT函数不同&#…

transformer——多变量预测PyTorch搭建Transformer实现多变量多步长时间序列预测(负荷预测)——transformer多变量预测

写在最前&#xff1a; 在系统地学习了Transformer结构后&#xff0c;尝试使用Transformer模型对DNA序列数据实现二分类&#xff0c;好久前就完成了这个实验&#xff0c;一直拖着没有整理&#xff0c;今天系统的记录一下&#xff0c;顺便记录一下自己踩过的坑 &#xff08;需要…

OpenHarmony开发实战:GPIO控制器接口

功能简介 GPIO&#xff08;General-purpose input/output&#xff09;即通用型输入输出。通常&#xff0c;GPIO控制器通过分组的方式管理所有GPIO管脚&#xff0c;每组GPIO有一个或多个寄存器与之关联&#xff0c;通过读写寄存器完成对GPIO管脚的操作。 GPIO接口定义了操作GP…

Echarts 问题集锦

最近公司集中做统计图表&#xff0c;新手小白&#xff0c;真被Echarts折腾地不轻&#xff0c;怕自己年老记忆衰退&#xff0c;特地做一些记录。以备后面查阅。 1、X轴的 数据显示不全&#xff0c;间或不显示 很奇葩&#xff0c;我发现数据里有一个值为0.0&#xff0c;当这条记…

液压件工厂的MES解决方案:智能生产,高效未来

一、引言 虽然我国液压件行业发展迅速&#xff0c;但是大多数液压件生产企业规模小、自主创新能力不足&#xff0c;大部分液压产品处于价值链中低端。且由于技术、工艺、设备及管理等多方面的限制&#xff0c;高端液压件产品研发生产水平不足&#xff0c;无法形成有效的供给&a…

【linux】虚拟机安装 BCLinux-R8-U4-Server-x86_64

目录 一、概述 1.1移动云Linux系统订阅服务 CLS 1.2 大云天元操作系统BC-Linux 二、安装 一、概述 1.1移动云Linux系统订阅服务 CLS 移动云Linux系统订阅服务 CLS &#xff08;Cloud Linux Service&#xff09;为使用BC-Linux操作系统的用户提供标准维保服务以及高级技术支…

生物墨水的重要特性

生物打印技术正以前所未有的速度发展&#xff0c;为组织工程和再生医学领域带来了革命性的变革。然而&#xff0c;成功打印出功能性的三维结构&#xff0c;并将其应用于人体&#xff0c;离不开生物墨水这一关键材料。主要特性包括&#xff1a; 物理性质 表面张力: 表面张力影…

基于java+springboot+vue实现的社团管理系统(文末源码+Lw)270

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差&#…

Linux4(Docker)

目录 一、Docker介绍 二、Docker结构 三、Docker安装 四、Docker 镜像 五、Docker 容器 六、Docker 安装nginx 七、Docker 中的MySQL部署 一、Docker介绍 Docker&#xff1a;是给予Go语言实现的开源项目。 Docker的主要目标是“Build,Ship and Run Any App,Anywhere” 也…

LangChain入门学习笔记(七)—— 使用检索提高生成内容质量

大模型训练使用的数据是开放的、广泛的&#xff0c;因此它显得更加的通用。然而在有些应用场景下&#xff0c;用户需要使用自己的数据使得大模型生成的内容更加贴切&#xff0c;也有时候用户的数据是敏感的&#xff0c;无法提供出来给大模型进行通用性的训练。RAG技术就是一种解…

HarmonyOS APP应用开发项目- MCA助手(Day02持续更新中~)

简言&#xff1a; gitee地址&#xff1a;https://gitee.com/whltaoin_admin/money-controller-app.git端云一体化开发在线文档&#xff1a;https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/agc-harmonyos-clouddev-view-0000001700053733-V5注&#xff1a;…

Java Lambda语法介绍

目录 一、概述 二、Lambda语法的历史 2.1 Lambda名字的含义 2.2 Lambda的历史 三、Lambda语法的核心接口 3.1 Lambda的四大核心接口 3.1.1 概述 3.1.2 Consumer 接口 3.1.3 Supplier 接口 3.1.4 Function 接口,> 3.1.5 Predicate 接口 四、Lambda的引用 4.1 概…

启航IT世界:高考后假期的科技探索之旅

随着高考的落幕&#xff0c;新世界的大门已经为你们敞开。这个假期&#xff0c;不仅是放松身心的时光&#xff0c;更是为即将到来的IT学习之旅打下坚实基础的黄金时期。以下是一份专为你们准备的IT专业入门预习指南&#xff0c;希望能助你们一臂之力。 一&#xff1a;筑基篇&a…

(18)GPS/指南针(一)

文章目录 前言 1 GPS/指南针 2 RTK GPS 3 GPS驱动程序选项 4 GPS自动切换 5 高级用途 前言 Copter/Plane/Rover 支持与 GPS、指南针和其他定位技术的整合&#xff1a; 1 GPS/指南针 Avionics Anonymous GNSS CompassAvionics Anonymous CompassBeitain BN-220 GPS / B…

昇思MindSpore学习入门-模型训练

模型训练 模型训练一般分为四个步骤&#xff1a; 构建数据集。定义神经网络模型。定义超参、损失函数及优化器。输入数据集进行训练与评估。 现在我们有了数据集和模型后&#xff0c;可以进行模型的训练与评估。 构建数据集 首先从数据集 Dataset加载代码&#xff0c;构建…

RT-Thread Studio与CubeMX联合编程之rtthread stm32h743的使用(十一)spi设备SFUD驱动的使用

我们要在rtthread studio 开发环境中建立stm32h743xih6芯片的工程。我们使用一块stm32h743及fpga的核心板完成相关实验&#xff0c;核心板如图&#xff1a; 1.建立新工程&#xff0c;选择相应的芯片型号及debug引脚及调试器 2.编译下载&#xff0c;可以看到串口打印正常 3.…

超实用的80个网络基础知识!(非常详细)零基础入门到精通,收藏这一篇就够了

点击上方 网络技术干货圈&#xff0c;选择 设为星标 优质文章&#xff0c;及时送达 转载请注明以下内容&#xff1a; 来源&#xff1a;公众号【网络技术干货圈】 作者&#xff1a;圈圈 ID&#xff1a;wljsghq 基础网络概念 1. 网络基础概述 什么是计算机网络 计算机网络是一…

全自动封箱机:如何助力企业实现智能化升级

在飞速发展的工业自动化时代&#xff0c;全自动封箱机以其高效、精准、稳定的特点&#xff0c;成为了生产线上的不可或缺的一员。它不仅大大地提高了生产效率&#xff0c;降低了人工成本&#xff0c;更在产品质量控制、安全性等方面发挥了重要作用。星派将深入探讨全自动封箱机…