🎖️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> {
   
  // ...
}

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


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

目录
相关文章
|
前端开发 C#
C# 基于NPOI+Office COM组件 实现20行代码在线预览文档(word,excel,pdf,txt,png)
C# 基于NPOI+Office COM组件 实现20行代码在线预览文档(word,excel,pdf,txt,png)
载波相移CPS-SPWM调制方法的simulink建模与仿真
本课题研究载波相移CPS-SPWM调制方法的Simulink建模与仿真。CPS-SPWM通过在多个功率单元中引入载波相移,使开关动作错开,输出多电平PWM波形,接近理想正弦波。系统采用单极倍频调制波反相法,生成互补脉冲序列控制开关管通断。双极性CPS-PWM的电压电平数为n+1,基波分量是单个双极性PWM的N倍。仿真结果验证了该方法的有效性,核心程序基于MATLAB2022a实现。
|
11月前
|
存储 弹性计算 NoSQL
"从入门到实践,全方位解析云服务器ECS的秘密——手把手教你轻松驾驭阿里云的强大计算力!"
【10月更文挑战第23天】云服务器ECS(Elastic Compute Service)是阿里云提供的基础云计算服务,允许用户在云端租用和管理虚拟服务器。ECS具有弹性伸缩、按需付费、简单易用等特点,适用于网站托管、数据库部署、大数据分析等多种场景。本文介绍ECS的基本概念、使用场景及快速上手指南。
400 3
|
存储 数据处理 UED
计算机随机存取存储器(RAM )
【8月更文挑战第4天】
3577 8
|
存储 分布式计算 监控
Hadoop在云计算环境下的部署策略
【8月更文第28天】Hadoop是一个开源软件框架,用于分布式存储和处理大规模数据集。随着云计算技术的发展,越来越多的企业开始利用云平台的优势来部署Hadoop集群,以实现更高的可扩展性、可用性和成本效益。本文将探讨如何在公有云、私有云及混合云环境下部署和管理Hadoop集群,并提供具体的部署策略和代码示例。
462 0
|
API 开发者
【Azure API 管理】API Management service (APIM) 如何实现禁止外网访问
【Azure API 管理】API Management service (APIM) 如何实现禁止外网访问
162 0
|
网络架构
深入了解会话描述协议(SDP)
【8月更文挑战第24天】
826 0
|
SQL 关系型数据库 MySQL
proxysql修改默认系统配置
proxysql修改默认系统配置
193 0
|
Java 编译器 API
java.lang.NoClassDefFoundError:无法初始化类XXX
java.lang.NoClassDefFoundError:无法初始化类XXX
266 0
|
JavaScript Java Docker
使用 Dockerfile 构建和定制 Docker 镜像
Dockerfile是构建Docker镜像的文本文件,包含一系列指令,如`FROM`, `WORKDIR`, `COPY`, `RUN`, `EXPOSE`和`CMD`。它用于自动化`docker build`命令来创建Image。使用Dockerfile可以基于官方镜像定制应用镜像,方便应用容器化和扩展。基本流程包括选择基础镜像、设置工作目录、安装依赖、暴露端口和定义启动命令。构建镜像使用`docker build`,运行容器用`docker run`。了解并熟练使用Dockerfile能提升容器化部署效率。