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

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


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

目录
相关文章
|
6天前
|
安全 编译器 C++
【C/C++ 类型转换规则】一文了解C/C++ 中的类型转换规则,帮助你更好的编程
【C/C++ 类型转换规则】一文了解C/C++ 中的类型转换规则,帮助你更好的编程
23 0
|
6天前
|
存储 JavaScript 索引
TypeScript 中的元组类型:元组的特性、常见操作和注意事项
TypeScript 中的元组类型:元组的特性、常见操作和注意事项
135 1
|
6天前
|
算法 程序员 C++
踩坑记录:C++ 中通用引用与函数重载的深入探索
踩坑记录:C++ 中通用引用与函数重载的深入探索
19 0
|
6天前
|
JavaScript 安全
TypeScript 中的高级类型转换技术:映射类型、条件类型和类型推断
TypeScript 中的高级类型转换技术:映射类型、条件类型和类型推断
|
9月前
|
JavaScript
🎖️typeScrpt中如何返回正确的类型?
条件返回类型确实是 TypeScript 中非常有用的强大功能,它允许您根据参数的类型为函数指定不同的返回类型,从而实现更强的类型安全性。
54 0
|
10月前
|
存储 安全 Java
Java泛型-语法与常用实例
Java泛型-语法与常用实例
85 0
C语言——enum枚举实例、知识点。使用枚举,减少相同定义步骤,简洁数据1.1.5
枚举是C语言常见的一种基本数据类型,它可以避免多个整数定义的麻烦,使代码整洁干净易读如此一看,就觉得繁琐无比,大量重复#define xx明显增加代码量,且数值需自己一一对应而枚举,可以解决这种定义连续数值的过程当变量第一个值未自定义时,第一个枚举成员的默认值则为整型0,后续成员值依次加1,如此时MON=0,TUE=1,WED=2·····.........
C语言——enum枚举实例、知识点。使用枚举,减少相同定义步骤,简洁数据1.1.5
|
开发框架 数据库
GoFrame代码优化:使用gconv类型转换 避免重复定义map
最近一直在研究 GoFrame 框架,经过一段时间的使用、总结、思考,发现确实不失为一款非常值得使用的企业级开发框架。
354 0
|
网络协议 测试技术 Go
类型断言引出和基本使用|学习笔记
快速学习类型断言引出和基本使用
74 0
|
Java
Java泛型——限制可用类型
Java泛型——限制可用类型
124 0