typescript - 如何查看 Typescript 类型的完整扩展合约?

标签 typescript visual-studio-code algebraic-data-types

如果我有一个看起来有点像这样的类型集合:

type ValidValues = string | number | null
type ValidTypes = "text" | "time" | "unknown"

type Decorated = {
  name?: string | null
  type?: ValidTypes
  value?: ValidValues
  title: string
  start: number
}

type Injected = {
  extras: object
}

// overriding the types from Decorated
type Text = Decorated & Injected & {
  name: string
  type: "text"
  value: string
}

我的实际代码还有更多内容,但这显示了核心思想。我不想相信自己才能恰到好处地建立类型之间的关系。在所有类型代数之后,我想要工具向我展示 Text 的类型定义“评估”到什么。

因此对于上面的示例,我希望 Text 中指定的字段将覆盖之前在 Decorated 类型中所做的声明,以及假设的工具提示的输出应该给我看这样的东西:

{
  name: string
  type: "text"
  value: string
  title: string
  start: number
  extras: object
}

有没有方便的方式获取这些信息?

最佳答案

IntelliSense 显示的类型的快速信息经常留下一些不足之处;您通常会得到任何给定类型的单一表示,这对于您的目的来说可能过于简洁甚至过于冗长。有一些建议可以使其更加灵活(例如 microsoft/TypeScript#25784microsoft/TypeScript#28508 ),以便用户可以在其 IDE 中展开/折叠类型定义。但我不知道他们是否会在近期或什至遥远的将来采取行动,所以让我们不要坐以待毙。


这是一个类型别名,我有时会用它来尝试以您所说的方式扩展类型:

// expands object types one level deep
type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;

// expands object types recursively
type ExpandRecursively<T> = T extends object
  ? T extends infer O ? { [K in keyof O]: ExpandRecursively<O[K]> } : never
  : T;

那些使用 conditional type inference “复制”类型 T进入一个新的类型变量 O然后是类似身份的 mapped type它遍历复制类型的属性。

条件类型推断在概念上是一个空操作,但它用于 distribute union types并强制编译器评估条件的“真”分支(如果你重新定义 Expand<T> 没有它,有时编译器只会输出映射类型 {[K in keyof RelevantType]: RelevantType[K]} ,这不是你想要的想看看)。

Expand之间的区别和 ExpandRecursively是它是否应该按原样吐出属性类型(Expand),或者是否应该扩展属性类型(ExpandRecursively)。在递归情况下,不要试图深入到基本类型会有所帮助,所以这就是为什么 T extends object包括条件。


好的,让我们看看在您的类型上使用它时会发生什么。我们不需要 ExpandRecursively在你的情况下,但我们可以使用它......它给出相同的结果:

type ExpandedText = Expand<Text>;

当我们在 IDE(TypeScript Playground 和 VSCode)中将鼠标悬停在它上面时,显示为:

/* type ExpandedText = {
  name: string;
  type: "text";
  value: string;
  title: string;
  start: number;
  extras: object;
 } */

如你所愿。

Link to code

关于typescript - 如何查看 Typescript 类型的完整扩展合约?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57683303/

相关文章:

python - 如何在 Python 中定义代数数据类型?

reactjs - 类型 'undefined' 必须有一个返回迭代器的 '[Symbol.iterator]()' 方法

unit-testing - 带有 "declare var"的测试组件

typescript - 类型 'T' 不可分配给类型 'string'

c++ - 无法使用 lldb 和 VSCode 调试简单的 C++ 程序

javascript - Visual Studio Code JavaScript Intellisense 不适用于对象属性

C++ 获取 std::variant 当前帮助的类型的 std::typeindex

javascript - 类型 'replace' 上不存在属性 'IData' 。缺什么?

python - 在 VS Code 中自定义 "Python Interactive"窗口

haskell - ADT 名称。什么是 `Left a` ,然后是什么 `a` ,在 Haskell 中?