TypeScript实战系列之强力爆破泛型的困扰

news2024/11/29 4:46:05

目录

  • 介绍
    • 开始
    • 如何理解泛型语法
    • 泛型约束
    • 泛型默认值
    • 练习
    • 后续

介绍

泛型在typescript 中使用频率相当高,也给了初学者相当大的阻碍。希望这一篇文章,能帮助你们爆破它。

开始

下面通过模拟实现一个简易版本的axios来引入泛型的使用

// axios.ts
type Method =
  | 'get'
  | 'GET'
  | 'delete'
  | 'Delete'
  | 'head'
  | 'HEAD'
  | 'options'
  | 'OPTIONS'
  | 'post'
  | 'POST'
  | 'put'
  | 'PUT'
  | 'patch'
  | 'PATCH'


interface AxiosRequestConfig {
    baseURL?: string //便于为 axios 实例的方法传递相对 URL
    url?: string // 请求地址 
    /* 注 ? 表示可选 */
    method?: Method // 请求方法 可选
    data?: any // post、patch 等类型请求的数据 可选
    params?: any // post、patch 等类型请求的数据 可选
    headers?: any
    responseType?: XMLHttpRequestResponseType
}

type AxiosResponse= {
    /**
     * 响应的data数据
     */
    data: any
    /**
     * 响应的状态码
     */
    status: number
  }
  

type AxiosPromise = Promise<AxiosResponse>



class Axios {
   default:AxiosRequestConfig={
   }

   constructor(initConfig: AxiosRequestConfig) {
    console.log('axios---init');
   }

   get(url: string, config?: AxiosRequestConfig): AxiosPromise{
    return new Promise((resolve)=>{
        resolve({
            data: {},
            status:200,
        })
    })
   }
}

export const createInstance=(config: AxiosRequestConfig)=>{
   const instance = new Axios(config)
   return instance
}


用它来模拟请求

import {createInstance} from "./axios"

const axios = createInstance({
    baseURL:'https://some-domain.com/api/'
})

axios.get('user/list').then(res=>{
    const {data} = res
})

痛点
这时候 我们使用data 里的数据 是没有代码提示的,因为现在data的类型就是any。
在这里插入图片描述

这肯定对于我们开发来说是不方便的!

预期

对于不同的请求,返回的数据格式是不同的。希望每个请求开发者都能自己去定义接口的请求类型!

解决

使用泛型就能完美解决这个痛点!

改造 :

type Method =
  | 'get'
  | 'GET'
  | 'delete'
  | 'Delete'
  | 'head'
  | 'HEAD'
  | 'options'
  | 'OPTIONS'
  | 'post'
  | 'POST'
  | 'put'
  | 'PUT'
  | 'patch'
  | 'PATCH'


interface AxiosRequestConfig<T=unknown> {
    baseURL?: string //便于为 axios 实例的方法传递相对 URL
    url?: string // 请求地址 
    /* 注 ? 表示可选 */
    method?: Method // 请求方法 可选
    data?: T // post、patch 等类型请求的数据 可选
    params?: any // post、patch 等类型请求的数据 可选
    headers?: any
    responseType?: XMLHttpRequestResponseType
}

type AxiosResponse<T=unknown>= {
    /**
     * 响应的data数据
     */
    data: T
    /**
     * 响应的状态码
     */
    status: number
  }
  

type AxiosPromise<T> = Promise<AxiosResponse<T>>



class Axios {
   default:AxiosRequestConfig={
   }

   constructor(initConfig: AxiosRequestConfig) {
    console.log('axios---init');
   }

   get<T=unknown>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>{
    return new Promise((resolve)=>{
        resolve({
            //@ts-ignore
            data: {},
            status:200,
        })
    })
   }
}

export const createInstance=(config: AxiosRequestConfig)=>{
   const instance = new Axios(config)
   return instance
}

使用:

import {createInstance} from "./axios"

const axios = createInstance({
    baseURL:'https://some-domain.com/api/'
})

type UserType = {
    name:string,
    age:number
}

axios.get<UserType>('user/list').then(res=>{
    const {data} = res
})

在这里插入图片描述
在这里插入图片描述
总结: 泛型是一种用于创建可复用的函数或类的技术,它允许你在编写代码时指定类型参数,以使函数或类适用于不同类型的数据。

如何理解泛型语法

function identity<T>(arg: T): T {
    return arg;
}

看到 语法会感到陌生。它没有什么特别,可以把它类比于函数的入参,你可以随意去定义它的参数名,但是一般ts规范使用 大写的英文字母。
在这里插入图片描述
例如:T 就是接受的类型 ,T可以在。只有在外部使用它时 ,T的类型才被确定!

function identity<T>(arg: T): T {
    let temp:T;
    let str  = '123'
    str as T
    return arg;
}

也可以接受多个外部类型

function cross<T,K>(arg1: T,arg2:K): T&K {
    return {
        ...arg1,...arg2
    };
}

泛型约束

想要限制外部传入类型必须带有 length 属性,可以使用关键字 extends

function loggingIdentity<T>(arg: T): T {
    console.log(arg.length);
    return arg;
}

在这里插入图片描述
改造后

外部传入的类型 必须带有length 属性 ,否则校验不通过

function loggingIdentity<T extends {length:number}>(arg: T): T {
    console.log(arg.length);
    return arg;
}

loggingIdentity({a:12,length:22})

泛型默认值

泛型也支持给默认值


type arrType<T=string> = {
    list:Array<T>
}

let obj:arrType ={
    list: ['2','3']
}

let obj1:arrType<number> ={
    list: [1,2]
}

练习

实现一个函数 来通过属性值来获得对应的值

function getValueByKey(obj:any,key:string){
  return obj[key]
}

let obj = {
    name:'kd',
    age:35
}

let value = getValueByKey(obj,'name')

在这里插入图片描述

但是现在没有代码提示,需要使用泛型,一个代表传入对象的类型,一个代表传入key 的类型


function getValueByKey<T,K>(obj:T,key:K):T[K]{
  return obj[key]
}

在这里插入图片描述
因为 ts 不知道 T 和 K 的 关系 所以会报错,但是我们开发知道他们的关系 K 是 属于 T的 key值,于是我们给他们加上 类型限制!


function getValueByKey<T extends {[P:string]:any},K extends keyof T>(obj:T,key:K):T[K]{
  return obj[key]
}

keyof 关键字 后面再介绍, 它的作用是取 类型的 key 值的!
在这里插入图片描述
代码提示就出来了! 至于为啥使用的时候可以省略尖括号 是因为类型推断
在这里插入图片描述
这时候 T 代表 {name:string,age:number} K 代表 “name” | “age”

当然你也可以自己指定

function getValueByKey<T extends {[P:string]:any},K extends keyof T>(obj:T,key:K):T[K]{
  return obj[key]
}



let obj = {
    name:'kd',
    age:35
}

let value = getValueByKey<typeof obj, keyof typeof obj>(obj,'age')

后续

后面再会出一篇ts的高级篇,里面会涉及到更多的泛型的使用。

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

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

相关文章

10秒部署好 Serverless Web,我只告诉你一个人

谁还不知道Serverless&#xff1f; 上个月亚马逊云科技 re:Invent大会第一个演讲主题就是它。 每一个新技术概念的引入都伴随着生产力的提高&#xff0c;Serverless指的是一种构建和运行不需要服务器管理的应用程序的概念。 一个很有用的技术&#xff0c;这篇文章带你入门。…

alibabacloud学习笔记05(小滴课堂)

高并发下的微服务存在的问题 高并发下的微服务容错方案 介绍什么是分布式系统的流量防卫兵Sentinel 微服务引入Sentinel和控制台搭建 每个服务都加上这个依赖。 启动方式&#xff1a; 讲解AliababCloud微服务整合Sentinel限流配置实操 我们在order和video模块都加上。 分别启动…

网站接入QQ登录

开发者认证&#xff0c;创建应用&#xff1a; &#xff08;1&#xff09;先在 QQ 互联 QQ互联管理中心 进行个人开发者认证&#xff0c;并审核 &#xff08;2&#xff09;创建【网站应用】&#xff0c;填写正确信息&#xff0c;获得对应的 appid 与 appkey&#xff0c;并审核…

Redis——SpringBoot整合Redis实战

1、基本配置 1.1、引入依赖 首先&#xff0c;建立Maven项目&#xff0c;在Maven项目中引入pom.xml文件&#xff1a; <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> &l…

【HarmonyOS应用开发】后台提醒(十六)

简述 随着生活节奏的加快&#xff0c;我们有时会忘记一些重要的事情或日子&#xff0c;所以提醒功能必不可少。应用可能需要在指定的时刻&#xff0c;向用户发送一些业务提醒通知。例如购物类应用&#xff0c;希望在指定时间点提醒用户有优惠活动。为满足此类业务诉求&#xf…

机器学习 | 解析聚类算法在数据检测中的应用

目录 初识聚类算法 聚类算法实现流程 模型评估 算法优化 特征降维 探究用户对物品类别的喜好细分(实操) 初识聚类算法 聚类算法是一种无监督学习方法&#xff0c;用于将数据集中的对象按照相似性分组。它旨在发现数据中的内在结构和模式&#xff0c;将具有相似特征的数据…

Photoshop CS6 下载安装教程,保姆级教程,小白也能轻松搞的,附安装包

前言 Adobe Photoshop CS6强大的照片拍摄和突破性的新功能&#xff0c;用于复杂的图形、选择、逼真的绘画和装饰智能。创建惊人的高动态范围(HDR)图像。用逼真的笔触和混合的颜色绘画。消除噪音&#xff0c;添加种子&#xff0c;并绘制一个国家最先进的摄影设备的草图。凭借原…

【HarmonyOS应用开发】ArkUI 开发框架-进阶篇-Video组件的使用(十)

一、Video组件的使用 1、概述 在手机、平板或是智慧屏这些终端设备上&#xff0c;媒体功能可以算作是我们最常用的场景之一。无论是实现音频的播放、录制、采集&#xff0c;还是视频的播放、切换、循环&#xff0c;亦或是相机的预览、拍照等功能&#xff0c;媒体组件都是必不可…

MacBook有必要装清理软件吗?CleanMyMac的一些主要特点

MacBook是苹果公司的一款高端笔记本电脑&#xff0c;但是&#xff0c;随着使用时间的增长&#xff0c;MacBook也会出现一些问题&#xff0c;比如运行缓慢、卡顿、垃圾文件堆积、磁盘空间不足等。这些问题不仅影响了用户的使用体验&#xff0c;也可能对MacBook的寿命和安全性造成…

Shell脚本⑧免交互

目录 一.Here Document 1.定义 2.变量 &#xff08;1&#xff09;变量替换成实际值 &#xff08;2&#xff09;整行内容作为变量并输出结果 &#xff08;3&#xff09;多行注释 &#xff08;4&#xff09;自动划分磁盘免交互 二.Expect 1.定义 2.安装 3.免交互操作 …

django线上教育学习平台大数据分析系统python

随着互联网技术不断地发展&#xff0c;网络与大数据成为了人们生活的一部分&#xff0c;而线上教育平台大数据分析作为网上应用的一个全新的体现&#xff0c;由于其特有的便捷性&#xff0c;已经被人们所接受。目前主流的线上教育平台大数据分析服务不仅不明确并且管理盈利较低…

基于STM32的UART/USART数据传输的错误检测和纠错机制研究

在STM32微控制器中&#xff0c;UART/USART模块的数据传输可以通过错误检测和纠错机制来提高数据的可靠性。下面将介绍一些常用的错误检测和纠错机制&#xff0c;并提供一个示例代码来演示如何使用这些机制。 ✅作者简介&#xff1a;热爱科研的嵌入式开发者&#xff0c;修心和技…

SpringCloud-微服务概述、SpringCloud入门概述、服务提供与消费

1.学习前言 1.1 学习前提 熟练使用SpringBoot 微服务快速开发框架了解过Dubbo Zookeeper 分布式基础电脑配置内存不低于8G 1.2 文章大纲 Spring Cloud 五大组件 服务注册与发现——Netflix Eureka负载均衡&#xff1a; ​ 客户端负载均衡——Netflix Ribbon ​ 服务端负载…

Oracle喊你领取免费AI 助理级证书啦!

拿证秘籍如下&#xff1a; 1. 登录Oracle的考试中心网站&#xff1a;https://education.oracle.com/certification 2. 选择AI 助理级考试&#xff0c;考试代码&#xff1a;1Z0-1122-23&#xff0c;也可以点击这里直达 3. AI学习视频免费看&#xff0c;也可以选择不看 3.5 去…

一台机器上如何部署多个web项目

1、综述 随着计算机硬件水平的不断提高&#xff0c;往往不是一台机器上只部署一个web项目了&#xff0c;而是尽可能多部署几个项目&#xff0c;以用来节省资源&#xff0c;现在我们看看如何一台机器部署多个项目&#xff0c;我们先结合上一篇文章中提到的tomcat架构&#xff0…

重温《深入理解Java虚拟机:JVM高级特性与最佳实践(第二版)》 –– 学习笔记(二)

第二部分&#xff1a;自动内存管理机制 第2章&#xff1a;Java内存区域与内存溢出异常 2.1 概述 Java 与 C 之间有一堵由内存动态分配和垃圾收集技术围成的高墙。 Java 程序员在 虚拟机自动内存管理机制 的帮助下&#xff0c;无需为每一个 new 操作去写配对的 delete/free …

TOP100-链表(四)

9.24. 两两交换链表中的节点 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 示例 1&#xff1a; 输入&#xff1a;head [1,2…

myql 项目数据库和表的设计

1.表的设计和创建 2.在navicate运行这些代码 create table user(id int not null auto_increment primary key,name varchar(50) not null unique,password varchar(50) not null,state enum(online,offline) default offline ); create table friend(userid int not null,…

java之ReentrantLock

在讲RentrantLock之前需要先讲一下AQS和LockSupport&#xff0c;因为rentrantLock底层是用AQS实现的&#xff0c;而AQS中获取阻塞和唤醒底使用LockSupport实现的。 1、LockSupport实现 下面代码中&#xff0c;LockSupport.park方法是当前线程等待&#xff0c;直到获得许可&am…

06:原生云K8S解密|K8S集群安装部署|K8S网络插件

原生云K8S解密&#xff5c;K8S集群安装部署&#xff5c;K8S网络插件 K8SK8S集群架构图解 K8S部署仓库初始化kube-master安装计算节点的安装token管理 配置flannel网络&#xff08;master主机操作&#xff09; K8S 有大量夸主机的容器需要管理&#xff0c;快速部署应用&#xff…