当前位置: 首页 > 知识库问答 >
问题:

前端 - TypeScript为何需要定义比较复杂的泛型类型?

燕烨
2024-08-29

有看到过定义比较复杂的泛型类型:

/** A complex generic type. */
export type ComplexGenericTypeAlias<T> =
    | T
    | T[]
    | Promise<T>
    | Promise<T[]>
    | Record<string, Promise<T>>;

请问下,为何需要定义这么多或的Type呢?

为何不直接定义:

type AAA<T> = T
type BBB<T> = T[]
type CCC<T> = Promise<T>
...

为何需要把这些风马牛不相及的类型(T, Promise, Record)组在一起?

共有2个答案

华良平
2024-08-29

为了complexGenericTypeAlias这个函数的返回值,
不然按你直接这么定义,返回值不方便写

type AAA<T> = T
type BBB<T> = T[]
type CCC<T> = Promise<T>
/** A complex generic type. */
export type ComplexGenericTypeAlias<T> =
    | T
    | T[]
    | Promise<T>
    | Promise<T[]>
    | Record<string, Promise<T>>;

function complexGenericTypeAlias<T>(value: T): ComplexGenericTypeAlias<T>  {
    if (value === 'array') {
        return [value]
    }
    if (value === 'promise') {
        return Promise.resolve(value)
    }
    if (value === 'promiseArray') {
        return Promise.resolve([value])
    }
    if (value === 'promiseRecord') {
        return { key: Promise.resolve(value) }
    }
    return value
}
尹光辉
2024-08-29

在TypeScript中定义复杂的泛型类型(如你给出的ComplexGenericTypeAlias<T>)主要出于以下几个原因:

  1. 类型安全性和灵活性:通过将多种可能的数据类型组合成一个单一的泛型类型别名,可以在保持类型安全的同时,增加函数或接口使用的灵活性。这样的类型定义允许开发者传入或接收多种不同的类型,而无需为每种可能的类型都定义一个单独的接口或类型别名。
  2. 减少代码冗余:如果没有这样的复杂泛型类型,开发者可能会发现自己需要为每种可能的类型组合创建单独的类型定义(如你所提出的AAA<T>, BBB<T>, CCC<T>等)。这会导致代码冗余,并且当需要扩展支持的类型时,需要添加更多的类型定义。使用复杂泛型类型可以显著减少这种冗余。
  3. 提高代码的可读性和可维护性:通过使用一个复杂的泛型类型别名,可以在函数或接口的签名中清晰地表示该函数或接口可以处理的数据类型范围。这有助于其他开发者(或未来的你)更快地理解代码的功能和限制。
  4. 支持复杂的业务逻辑:在某些业务场景中,可能需要处理多种类型的数据,并且这些数据类型之间可能存在复杂的转换和依赖关系。通过定义一个包含这些类型的复杂泛型类型别名,可以更容易地在代码中处理这些复杂情况。
  5. 类型推断的便捷性:TypeScript的类型推断功能非常强大,但在某些情况下,如果函数或接口的参数类型不够明确,可能会导致类型推断失败或结果不准确。通过使用复杂的泛型类型别名,可以为TypeScript的类型推断器提供更多的上下文信息,从而提高类型推断的准确性和便捷性。

综上所述,定义复杂的泛型类型是为了在保持类型安全的同时,提高代码的灵活性、可读性、可维护性和类型推断的便捷性。这种做法在处理复杂的数据结构和业务逻辑时尤其有用。

 类似资料:
  • 我有一个对象,其中包含另一个对象类型的属性,我想将其视为复杂类型。 在添加迁移时,我遇到了需要主键的问题(这正是我想要防止的)。 实体类型坐标需要定义主键。 编辑 出于性能原因,我希望属性存储为和,而不是对另一个表的引用。

  • 问题内容: 在Java中,我编写了一个Binary Search Tree类,该类使用递归添加节点。现在,我想使用泛型对其进行概括,以便我可以了解更多有关它们的信息。 我添加节点的功能在以下类中 主类具有以下代码来开始工作。我正在使用字符串,但是数据类型可能是一些复杂的类型。 我开始使用Comparable接口,但是如何编写CompareTo()函数?我不知道T是什么类型的?我得到的错误是“运算符

  • 为泛型定义要求 如类型约束中描述的一样, 类型约束允许你在泛型函数或泛型类型相关的类型形式参数上定义要求. 类型约束在为关联类型定义要求时也很有用.通过定义一个泛型Where子句来实现. 泛型Where子句让你能够要求一个关联类型必须遵循指定的协议, 或者指定的类型形式参数和关联类型必须相同. 泛型Where子句以Where关键字开头, 后面关联类型的约束或类型和关联类型一致的关系. 泛型Wher

  • 如上面代码所示,需要指定 arr 参数的数据类型,这个数据数据类型是 p1 或者 p2 参数的 key.请问这个改如何指定呢。

  • 问题内容: 我需要哪些键中的一个或类,并且其值是这两个类中的一个,的对象列表 分别 。 例如: 我试过了,但是没有编译。 确实可以编译,但是在这种情况下不应该同时编译大小写和案例。 可能吗? 问题答案: 我认为不可能在类型中对此进行编码,我会使用自定义类来实现 只要您不将参考泄漏到此类之外,就可以在此处禁止显示警告。

  • 通常看到定义一个 promise 的类型都采用 Promise<string> 的方式,表示 resolved 时返回一个 string 的类型值,但是会忽略 rejected 后应该返回什么类型,这是故意这么设计的吗?

  • 为什么需要泛型 前言 泛型程序最早出现1970年代的CLU和Ada语言中, 后来被许多机遇对象和面向对象的语言锁采用 1993年C++在3.0版本中引入的模板技术就属于泛型编程 1994年7月ANSI/ISO C++标准委员会通过的STL更是泛型编程的集大成者, 它已被纳入1998年9月C++标准之中. 2004年9月Java在J2SE 5.0(JDK 1.5)中开始使用泛型技术; 2005年11

  • 考虑一个具有的API,如下所示: 很简单,只有页面大小和跳过计数属性。 此外,现在我还有一些类,它们也包含但未分页。 在我的测试中,我希望他们都能实现一个接口,这样我就可以用一些更基本的测试来生成一个通用的基本测试类。为此,我添加了我认为会起作用的内容: 我将PagedResults更改为: 错误 但现在编译器抱怨PagedResultBase继承的所有地方的使用情况(?)从。 但是,如果我将接口