TS学习-泛型基础

news2024/11/26 13:25:45

目录

  • 1,介绍
    • 1,在函数中使用
    • 2,在类型别名,接口中使用
    • 3,在类中使用
  • 2,泛型约束
  • 3,多泛型
  • 4,举例实现 Map

1,介绍

泛型相当于是一个类型变量,有时无法预先知道具体的类型,可以用泛型来代替。

通常会附属于函数,类,接口,类型别名之上。

举例:

在定义函数时,有时会丢失一些类型信息(多个位置应该保持一致)。

function handleArray(arr: any[], n: number): any[] {
    const temp: any[] = arr.slice(n)
    return temp
}

handleArray([1,2,30], 2)
handleArray(['1', '2', '3'], 2)

当传递 number 类型数组时,上面代码中所有 any[] 都应该是 number[],string 数组同理。

泛型来解决:

function handleArray<T>(arr: T[], n: number): T[] {
    const temp: T[] = arr.slice(n)
    return temp
}

handleArray<number>([1,2,30], 2)
handleArray<string>(['1', '2', '3'], 2)

1,在函数中使用

使用方式:定义函数和调用函数时,都在函数名之后使用 < > 来定义泛型名称

function handleArray<T>(arr: T[]): T[] {
   // ...
}

handleArray<number>()
handleArray<string>()

泛型对函数来说:在调用函数时,告诉函数操作的具体类型,函数在执行时就能确定具体的类型。

特点

1,只有在调用时,才能确定泛型的具体类型。

2,一般情况下,TS会智能的根据传递的参数,推导出泛型的具体类型。

以上面的例子来说,即便调用时没有写具体的泛型类型,函数也会根据传递的参数智能推导:

在这里插入图片描述

如果无法完成推导,并且没有传递具体的类型,默认为 unknown

function handleArray<T>(arr: any[], n: number): T[] {
    const temp: T[] = arr.slice(n)
    return temp
}

// unknown[]
const res = handleArray([1,2,30], 2)

3,泛型也可以有默认值。

几乎用不到,因为泛型就是用来表示可能得任意类型。

function handleArray<T = number>(arr: T[]): T[] {
    // ...
}

2,在类型别名,接口中使用

看例子即可,实现一个 filter 函数。

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

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

interface callback<T> {
    (n: T, i: number): boolean;
}

function filter<T>(arr: T[], callback: callback<T>): T[] {
    let temp: T[] = [];
    arr.forEach((n, i) => {
        if (callback(n, i)) {
            temp.push(arr[i]);
        }
    });
    return temp;
}

const res = filter([1, 2, 3, 4], (n, i) => n % 2 !== 0);
console.log(res);

3,在类中使用

类名上指定的泛型,可以传递到定义的属性和方法上。

type callback<T> = (item: T, index?: number, arr?: T[]) => boolean;

class ArrayHelper<T> {
	constructor(private arr: T[]) {}

	myFilter(callback: callback<T>): T[] {
		let tempArr: T[] = [];
		this.arr.forEach((item, index, arr) => {
			if (callback(item, index, arr)) {
				tempArr.push(item);
			}
		});
		return tempArr;
	}
}

const tempArr = new ArrayHelper([2, 3, 4, 5]);

const res = tempArr.myFilter((item) => item % 2 === 0);

console.log(res);

2,泛型约束

用于约束泛型的取值:必须得有类型约束(接口,类型别名)中的成员。

举例:泛型必须兼容 User 接口。

interface User {
    name: string;
}

function updateName<T extends User>(obj: T): T {
    obj.name = obj.name.toUpperCase();
    return obj;
}

const obj = {
    name: "lover",
    age: 19,
};

const newNameObj = updateName(obj);
console.log(newNameObj);

3,多泛型

函数的参数会有多个,所以泛型也会有多个。

举例,混合2个不同类型的数组。

function mixinArray<T, K>(arr1: T[], arr2: K[]): (T | K)[] {
    const temp: (T | K)[] = [];
    for (let i = 0; i < arr1.length; i++) {
        temp.push(arr1[i]);
        temp.push(arr2[i]);
    }
    return temp;
}

console.log(mixinArray([1, 2], ["11", "22"]));

4,举例实现 Map

这是 Map 的接口定义

interface Map<K, V> {
    clear(): void;
    /**
     * @returns true if an element in the Map existed and has been removed, or false if the element does not exist.
     */
    delete(key: K): boolean;
    /**
     * Executes a provided function once per each key/value pair in the Map, in insertion order.
     */
    forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void;
    /**
     * Returns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
     * @returns Returns the element associated with the specified key. If no element is associated with the specified key, undefined is returned.
     */
    get(key: K): V | undefined;
    /**
     * @returns boolean indicating whether an element with the specified key exists or not.
     */
    has(key: K): boolean;
    /**
     * Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
     */
    set(key: K, value: V): this;
    /**
     * @returns the number of elements in the Map.
     */
    readonly size: number;
}

简单模拟实现:

class MyMap<K, V> {
    private keys: K[] = [];
    private values: V[] = [];

    get size() {
        return this.keys.length;
    }

    clear(): void {
        this.keys = [];
        this.values = [];
    }

    delete(key: K): boolean {
        const index = this.keys.indexOf(key);
        if (index !== -1) {
            this.keys.splice(index, 1);
            this.values.splice(index, 1);
            return true;
        } else {
            return false;
        }
    }

    forEach(callbackfn: (value: V, key: K, map: MyMap<K, V>) => void): void {
        this.keys.forEach((item, i) => {
            callbackfn(this.values[i], item, this);
        });
    }

    get(key: K): V | undefined {
        const index = this.keys.indexOf(key);
        return this.values[index];
    }

    has(key: K): boolean {
        return return this.keys.includes(key);
    }

    set(key: K, value: V): this {
        const index = this.keys.indexOf(key);
        if (index !== -1) {
            this.keys.push(key);
            this.values.push(value);
        } else {
            this.values[index] = value;
        }
        return this;
    }
}

const myMap = new MyMap<string, number>();

myMap.set("a", 1);
myMap.set("b", 2);
myMap.set("c", 3);
console.log(myMap.get("d"));
myMap.has("a");
console.log(myMap.delete("c"));

myMap.forEach((value, key, self) => {
    console.log(value, key, self);
});

myMap.clear();
console.log(myMap.size);

以上。

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

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

相关文章

【每日刷题】Day30

【每日刷题】Day30 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 牛牛的链表添加节点_牛客题霸_牛客网 (nowcoder.com) 2. 牛牛的链表删除_牛客题霸_牛客网 (nowcoder…

Django整合多种认证方式

承接上一篇&#xff1a;Django知识点总结-CSDN博客 目录 25.使用 Django REST framework实现用户认证和授权 26.通过djangorestframework-simplejwt使用JWT(JSON Web Token) 27.使用django-auth-ldap进行用户认证 28. 使用django-cas-ng实现集中认证及实现单点登录 29. …

c# winform快速建websocket服务器源码 wpf快速搭建websocket服务 c#简单建立websocket服务 websocket快速搭建

完整源码下载----->点击 随着互联网技术的飞速发展&#xff0c;实时交互和数据推送已成为众多应用的核心需求。传统的HTTP协议&#xff0c;基于请求-响应模型&#xff0c;无法满足现代Web应用对低延迟、双向通信的高标准要求。在此背景下&#xff0c;WebSocket协议应运而生…

C++函数重载之类型引用和类型本身

在C中&#xff0c;当我们讨论类型引用&#xff08;也称为引用类型&#xff09;与类型本身被视为“同一个特征标”&#xff08;signature&#xff09;时&#xff0c;我们实际上是在讨论引用类型在函数重载解析&#xff08;function overload resolution&#xff09;和模板参数推…

Github 2024-05-02 Go开源项目日报 Top10

根据Github Trendings的统计,今日(2024-05-02统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Go项目10PureBasic项目1Kubernetes: 容器化应用程序管理系统 创建周期:3618 天开发语言:Go协议类型:Apache License 2.0Star数量:106913 个…

C#知识|Dictionary泛型集合的使用总结

哈喽,你好,我是雷工! 以下是C#Dictionary泛型集合的学习笔记。 01 Dictionary泛型集合 1.1、Dictionary<K,V>通常称为字典, 1.2、其中<K,V>是自定义的,用来约束集合中元素类型。 1.3、在编译时检查类型约束, 1.4、无需装箱拆箱操作, 1.5、操作与哈希表(Ha…

美国零售媒体(广告业)指南:快速增长、不断扩展的业态和新兴机遇

Guide to retail media: Rapid growth, expanding formats, and emerging opportunities --- 零售媒体如何通过CTV和其他合作伙伴关系向上发展 原文作者&#xff1a;Sara Lebow | 2024年2月16日 整理编辑&#xff1a;数字化营销工兵 I 2024年5月2日 ​​​​​​​ &#…

基于HAL库的stm32中定时器的使用--定时器中断每隔一秒进行led灯的闪烁以及定时器生成PWM

一&#xff1a;什么是定时器 &#xff08;1&#xff09;stm32定时器&#xff0c;是存在于stm32单片机中的一个外设。stm32共有八个定时器&#xff0c;两个高级定时器&#xff08;TIM1、TIM8&#xff09;&#xff0c;四个通用定时器&#xff08;TIM2、TIM3、TIM4、TIM5&#xff…

B树:原理、操作及应用

B树&#xff1a;原理、操作及应用 一、引言二、B树概述1. 定义与性质2. B树与磁盘I/O 三、B树的基本操作1. 搜索&#xff08;B-TREE-SEARCH&#xff09;2. 插入&#xff08;B-TREE-INSERT&#xff09;3. 删除&#xff08;B-TREE-DELETE&#xff09; 四、B树的C代码实现示例五、…

selenium 4.x 之验证码处理(python)

验证码处理 一般情况公司如果涉及web自动化测试需要对验证码进行处理的方式一般有一下几种&#xff1a; 关闭验证码功能&#xff08;开发处理&#xff09;设置万能验证码&#xff08;开发处理&#xff09;使用智能识别库进行验证 通过第三方打码平台识别验证码 1. 跳过验证功…

[基础] Unity Shader:顶点着色器(vert)函数

顶点着色器&#xff08;Vertex Shader&#xff09;是图形渲染的第一个阶段&#xff0c;它的输入来自于CPU。顶点着色器的处理单位是顶点&#xff0c;CPU输入进来的每个顶点都会调用一次顶点着色器函数&#xff0c;也就是我们在Shader代码里所定义的vert函数。本篇我们将会通过顶…

uniapp+vue社区车位预订租赁系统 微信小程序

本私家车位共享系统有管理员&#xff0c;用户两个角色。管理员可以对用户信息&#xff0c;车辆类型信息进行管理&#xff0c;并且可以审核用户提交的租赁订单&#xff0c;用户可以注册登录&#xff0c;新增车辆信息&#xff0c;查看车位信息并且租赁&#xff0c;并且可以支付。…

SQL 基础 | UNION 用法介绍

在SQL中&#xff0c;UNION操作符用于合并两个或多个SELECT语句的结果集&#xff0c;形成一个新的结果集。 使用UNION时&#xff0c;合并的结果集列数必须相同&#xff0c;并且列的数据类型也需要兼容。 默认情况下&#xff0c;UNION会去除重复的行&#xff0c;只保留唯一的行。…

企业计算机服务器中了lockbit勒索病毒如何处理,lockbit勒索病毒解密流程建议

在虚拟的网络世界里&#xff0c;人们利用网络获取信息的方式有很多&#xff0c;网络为众多企业提供了极大便利性&#xff0c;也大大提高了企业生产运营效率&#xff0c;方便企业开展各项工作业务。但随着网络技术的不断发展与应用&#xff0c;越来越多的企业开始关注企业网络数…

06 - metastore服务、hive服务启动脚本以及相关使用技巧

目录 1、metastore服务 1.1、metastore运行模式 1.2、metastore部署 1.3、测试 2、编写Hive服务启动脚本 3、Hive使用技巧 3.1、Hive常用交互命令 3.2、Hive参数配置方式 3.3、Hive常见属性配置 1、metastore服务 Hive的metastore服务的作用是为Hive CLI或者Hiveserv…

linux内核源码分析--核心网络文件和目录

图3-2显示了在/proc/sys中由网络代码所使用的主要目录&#xff0c;就每个目录而言&#xff0c;都列出了在哪一章描述其文件。 proc/sys/net bridge ipv4 core route neigh conf 图3-2/proc/sys/net 中的核心目录 根据前借所述&#xff0c;我们来看net中的树根是如何定义的&…

SpringCloudAlibaba:3.1dubbo

dubbo 概述 简介 Apache Dubbo 是一款 RPC 服务开发框架&#xff0c;用于解决微服务架构下的服务治理与通信问题 官方提供了 Java、Golang、Rust 等多语言 SDK 实现 Dubbo的开源故事 最早在2008年&#xff0c;阿里巴巴就将Dubbo捐献到开源社区&#xff0c;它很快成为了国内开源…

R语言的学习—5—多元数据直观表示

1、数据读取 ## 数据整理 d3.1read.xlsx(adstats.xlsx,d3.1,rowNamesT);d3.1 #读取adstats.xlsx表格d3.1数据 barplot(apply(d3.1,1,mean)) #按行做均值条形图 barplot(apply(d3.1,1,mean),las3) barplot(apply(d3.1,2,mean)) #按列做均值图条形图 barplot(a…

JavaEE >> Spring MVC(1)

MVC MVC&#xff1a;Model View Controller 的缩写&#xff0c;是一种软件架构模式&#xff0c;将软件系统分为模型、视图和控制器三个部分。 Mode&#xff08;模型&#xff09;&#xff1a;是应⽤程序中⽤于处理应⽤程序数据逻辑的部分。通常模型对象负责在数据库中存取数据…

【C++STL详解(五)】--------list的介绍与使用

目录 前言 一、list的介绍 二、list的使用 Ⅰ.默认成员函数 1、构造函数 2、赋值重载 3、析构函数 Ⅱ、容量 1.size() Ⅲ、迭代器与遍历 1.beginend (正向迭代器) 2.rbeginrend (反向迭代器) 3.front 4.back Ⅳ、增删查改 1.push_front 2.pop_front 3.push_b…