🎖️typeScrpt中如何使用条件类型和泛型?

简介: 我将通过一个可能对日常使用非常有帮助的代码示例更深入地介绍泛型。

嗨,大家好!这里是道长王jj~ 🎩🧙‍♂️

我将通过一个可能对日常使用非常有帮助的代码示例更深入地介绍泛型。

我们有一个函数,根据作为参数传递的格式,可以将对象序列化为不同的格式:

type JsonFormat = {
    type: "json" };
type BinaryFormat = {
    type: "binary" };
type StreamFormat = {
    type: "stream" };
type Format = JsonFormat | BinaryFormat | StreamFormat;

function serialize(
  obj: Record<string, unknown>,
  format: Format,
): any {
   
  // ...
}

我们期望每个函数调用的返回类型根据格式而异:

const data = {
    a: 1, b: 2 };
// 格式为 json,返回类型应为字符串
const s1 = serialize(data, {
    type: "json" });  
// 格式为 binary,返回类型应为 Uint8Array  
const s2 = serialize(data, {
    type: "binary" });  
// 格式为 stream,返回类型应为 ReadableStream<Uint8Array>
const s3 = serialize(data, {
    type: "stream" });

为了实现这一点,我们需要将 format 参数的类型连接到函数的实际返回类型。首先,在函数签名中添加一个泛型类型参数 TFormat

// ...
type Format = JsonFormat | BinaryFormat | StreamFormat;

function serialize<TFormat extends Format>(
  obj: Record<string, unknown>,
  format: TFormat,
): any {
   
  // ...
}

泛型类型参数 TFormat 使用 extends 关键字将类型限制为特定类型或类型集。在这种情况下,它确保只有 Format 联合类型的子类型可以用作输入参数。

接下来,我们创建泛型类型 SerializeReturnType 来为每种格式选择正确的返回类型:

// ...
type Format = JsonFormat | BinaryFormat | StreamFormat;

type SerializeReturnType<TFormat extends Format> = 
  TFormat extends JsonFormat 
  ? string
  : TFormat extends BinaryFormat
  ? Uint8Array
  : TFormat extends StreamFormat
  ? ReadableStream<Uint8Array>
  : never;

// ...

这个泛型类型根据泛型类型参数 TFormat 返回正确的类型。类型定义使用条件类型将每种可能的格式映射到其相应的返回类型。 ?: 字符序列实际上是嵌套的三元表达式。因此,您可以将此类型定义视为 if-else-if 梯形:

  • 如果 TFormatJsonFormat,则返回类型是 string
  • 否则,如果 TFormatBinaryFormat,则返回类型是 Uint8Array
  • 否则,如果 TFormatStreamFormat,则返回类型是 ReadableStream<Uint8Array>
  • 否则,如果 TFormat 不是这三种类型之一,返回类型是 never,这意味着该函数不能返回任何内容。

最后,我们需要将参数 format 的泛型类型连接到函数的泛型返回类型:

// ...
type Format = JsonFormat | BinaryFormat | StreamFormat;

type SerializeReturnType<TFormat extends Format> = 
  TFormat extends JsonFormat 
  ? string
  : TFormat extends BinaryFormat
  ? Uint8Array
  : TFormat extends StreamFormat
  ? ReadableStream<Uint8Array>
  : never;

function serialize<TFormat extends Format>(
  obj: Record<string, unknown>,
  format: TFormat,
): SerializeReturnType<TFormat> {
   
  // ...
}

这样,函数的返回类型会根据传递的格式而自动确定,并且在类型检查中会得到正确的类型信息。它展示了泛型的强大功能,使我们能够根据参数的类型来推断返回类型。


🎉 你觉得怎么样?这篇文章可以给你带来帮助吗?当你处于这个阶段时,你发现什么对你帮助最大?如果你有任何疑问或者想进一步讨论相关话题,请随时发表评论分享您的想法,让其他人从中受益。🚀✨

目录
相关文章
|
2月前
|
安全 JavaScript
文本字符数统计 在线工具分享
专为内容创作者设计的在线字数统计工具!支持实时统计中/英文、数字、空格等字符数,无需注册、不传数据,隐私安全。适配公众号、小红书、作业、简历等多场景,手机电脑即开即用。
660 7
|
5月前
|
消息中间件 缓存 NoSQL
【Redis进阶】不止是缓存!Redis的5种核心数据结构与实战场景全解析
本文深入浅出地解析了Redis五大核心数据结构:String、Hash、List、Set和ZSet,结合图解与实战场景,涵盖缓存、计数器、分布式锁、购物车、消息队列、排行榜等典型应用,助你摆脱“只会SET/GET”的困境,真正发挥Redis的高性能潜力。
|
11月前
|
测试技术 Python
Python接口自动化测试中Mock服务的实施。
总结一下,Mock服务在接口自动化测试中的应用,可以让我们拥有更高的灵活度。而Python的 `unittest.mock`库为我们提供强大的支持。只要我们正确使用Mock服务,那么在任何情况下,无论是接口是否可用,都可以进行准确有效的测试。这样,就大大提高了自动化测试的稳定性和可靠性。
406 0
|
安全 数据库 数据安全/隐私保护
新网温馨提示:当前链接地址或网站因含有违规内容,暂时无法访问的解决方案
某上海客户的家具网站最近被新网拦截了,直接输入网站域名访问提示:当前链接地址或网站因含有违规内容,暂时无法访问。目前客户做了百度竞价推广,一天消费在500左右,由于网站打不开,损失惨重,通过朋友介绍找到我们SINE安全,根据客户目前的情况我们随即成立网站安全应急响应组,针对网站被新网拦截的问题,进行紧急处理,下面记录分享一下我们的处理过程和解决办法。首先我们来看下网站被新网拦截的截图:
3412 0
新网温馨提示:当前链接地址或网站因含有违规内容,暂时无法访问的解决方案
|
存储 分布式计算 监控
Hadoop在云计算环境下的部署策略
【8月更文第28天】Hadoop是一个开源软件框架,用于分布式存储和处理大规模数据集。随着云计算技术的发展,越来越多的企业开始利用云平台的优势来部署Hadoop集群,以实现更高的可扩展性、可用性和成本效益。本文将探讨如何在公有云、私有云及混合云环境下部署和管理Hadoop集群,并提供具体的部署策略和代码示例。
1110 0
|
Java 编译器 API
java.lang.NoClassDefFoundError:无法初始化类XXX
java.lang.NoClassDefFoundError:无法初始化类XXX
441 0
|
JavaScript Java Docker
使用 Dockerfile 构建和定制 Docker 镜像
Dockerfile是构建Docker镜像的文本文件,包含一系列指令,如`FROM`, `WORKDIR`, `COPY`, `RUN`, `EXPOSE`和`CMD`。它用于自动化`docker build`命令来创建Image。使用Dockerfile可以基于官方镜像定制应用镜像,方便应用容器化和扩展。基本流程包括选择基础镜像、设置工作目录、安装依赖、暴露端口和定义启动命令。构建镜像使用`docker build`,运行容器用`docker run`。了解并熟练使用Dockerfile能提升容器化部署效率。
|
缓存 Java 开发者
Java中多线程创建方式对比与线程池相关原理概述汇总(超详细)
Java中多线程创建方式对比与线程池相关原理概述汇总(超详细) 准备加入阿里开发者社区,同时也是很久没有写文章了,一时也不知道从何写起,那就先从多线程来吧,这次想把多线程与高并发的相关知识进行一下梳理,从多线程的几种创建方式开始,逐步到线程池原理分析,再到java中常用锁的使用场景与原理分析,再到高并发的处理方案,以及后面分布式锁等知识点,分成批次来进行梳理,这次先分析一下多线程的创建方式的异同点与线程池的执行原理。
1696 3
Java中多线程创建方式对比与线程池相关原理概述汇总(超详细)
|
Linux 网络安全 Apache
安装Apache之后,在浏览器中无法访问问题
安装Apache之后,在浏览器中无法访问问题
483 0