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

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


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

目录
相关文章
|
分布式计算 Java 数据安全/隐私保护
Kotlin 学习笔记(二)—— 数据类、枚举类、循环、常用集合及操作符的写法(下 )
Kotlin 学习笔记(二)—— 数据类、枚举类、循环、常用集合及操作符的写法(下)
69 0
|
6月前
|
安全 API C#
C#.Net筑基-类型系统②常见类型--枚举Enum
枚举(enum)是C#中的一种值类型,用于创建一组命名的整数常量。它们基于整数类型(如int、byte等),默认为int。枚举成员可指定值,未指定则从0开始自动递增。默认值为0。枚举可以与整数类型互相转换,并可通过`[Flags]`特性表示位域,支持位操作,用于多选场景。`System.Enum`类提供了如`HasFlag`、`GetName`等方法进行枚举操作。
|
5月前
|
开发框架 .NET 程序员
掌握C#语言的精髓:基础知识与实用技能详解(数据类型与变量+ 条件与循环+函数与模块+LINQ+异常+OOP)
掌握C#语言的精髓:基础知识与实用技能详解(数据类型与变量+ 条件与循环+函数与模块+LINQ+异常+OOP)
33 0
|
6月前
|
算法 编译器 C++
【C++ 模板编程 基础知识】C++ 模板类部分特例化的参数顺序
【C++ 模板编程 基础知识】C++ 模板类部分特例化的参数顺序
40 0
|
JavaScript
🎖️typeScrpt中如何返回正确的类型?
条件返回类型确实是 TypeScript 中非常有用的强大功能,它允许您根据参数的类型为函数指定不同的返回类型,从而实现更强的类型安全性。
83 0
|
6月前
|
JavaScript 安全
TypeScript 中的高级类型转换技术:映射类型、条件类型和类型推断
TypeScript 中的高级类型转换技术:映射类型、条件类型和类型推断
|
存储 C++
【C++11保姆级教程】强类型枚举(强类型枚举)和constexpr
【C++11保姆级教程】强类型枚举(强类型枚举)和constexpr
196 0
|
存储 安全 Java
Java泛型-语法与常用实例
Java泛型-语法与常用实例
118 0
|
安全 JavaScript
学习TypeScrip2(任意类型)
TypeScript 3.0中引入的 unknown 类型也被认为是 top type ,但它更安全。与 any 一样,所有类型都可以分配给unknown
86 0
C语言——enum枚举实例、知识点。使用枚举,减少相同定义步骤,简洁数据1.1.5
枚举是C语言常见的一种基本数据类型,它可以避免多个整数定义的麻烦,使代码整洁干净易读如此一看,就觉得繁琐无比,大量重复#define xx明显增加代码量,且数值需自己一一对应而枚举,可以解决这种定义连续数值的过程当变量第一个值未自定义时,第一个枚举成员的默认值则为整型0,后续成员值依次加1,如此时MON=0,TUE=1,WED=2·····.........
C语言——enum枚举实例、知识点。使用枚举,减少相同定义步骤,简洁数据1.1.5