如果我有一个有点像这样的类型集合,只会更详细:

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中扩展/折叠类型定义.但我不知道他们是否会在不久甚至遥远的将来采取行动,所以我们不要等待.


下面是一个类型别名,我有时用它来try 以您所说的方式扩展类型:

// 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这样的标识来迭代复制的类型的属性.

条件类型推断在概念上是一个no op,但它用于distribute union types和强制编译器计算条件的"true"分支(如果没有它重新定义Expand<T>,有时编译器只会output映射类型{[K in keyof RelevantType]: RelevantType[K]},这不是您希望看到的).

ExpandExpandRecursively之间的区别在于,它是应该按原样(Expand)吐出属性类型,还是应该按原样(ExpandRecursively)吐出属性类型.在递归情况下,它有助于避免深入到基元类型,这就是为什么包含T extends object条件.


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

type ExpandedText = Expand<Text>;

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

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

如你所愿.好吧,希望这有帮助;祝你好运

Link to code

Typescript相关问答推荐

如何将@for的结果绑定到变量?

TypScript ' NoInfer '类型未按预期工作

在Angular中,如何在文件上传后清除文件上传文本框

如何在使用`Next—intl`和`next/link`时导航

键集分页顺序/时间戳上的筛选器,精度不相同

rxjs forkJoin在错误后不会停止后续请求

隐式键入脚本键映射使用

如何以Angular 形式显示验证错误消息

如何在已知基类的任何子类上使用`extends`?

如何使所有可选字段在打印脚本中都是必填字段,但不能多或少?

在排版修饰器中推断方法响应类型

为什么&Quot;元素隐式具有';Any';类型,因为...即使我已经打字了,也不能作为索引显示错误吗?

从非文字数组(object.keys和array.map)派生联合类型

如何在具有嵌套数组的接口中允许新属性

将类型脚本函数返回类型提取到VSCode中的接口

是否可以定义引用另一行中的类型参数的类型?

可以用任意类型实例化,该类型可能与

从泛型对象数组构造映射类型

如何将 MUI 主题对象的自定义属性与情感样式组件中的自定义props 一起使用?

元组解释