显示类型的快速信息智能感知常常留下一些不尽如人意的东西;您通常会得到任何给定类型的单一表示形式,这对于您的目的来说可能过于简洁甚至过于冗长。有一些建议可以使其更加灵活(例如,微软/TypeScript#25784 and 微软/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;
那些使用条件类型推断“复制”类型T
到一个新的类型变量中O
然后是类似身份的映射类型它迭代复制的类型的属性。
条件类型推断在概念上是无操作,但它用于分配联合类型并强制编译器评估条件的“true”分支(如果您重新定义Expand<T>
没有它,有时编译器只会output映射类型{[K in keyof RelevantType]: RelevantType[K]}
,这不是你想看到的)。
和...之间的不同Expand
and ExpandRecursively
是它是否应该按原样吐出属性类型(Expand
),或者如果应该expand财产类型(ExpandRecursively
)。在递归情况下,不要尝试深入研究原始类型会有所帮助,这就是为什么T extends object
条件已包括在内。
好的,让我们看看当我们在您的类型上使用它时会发生什么。我们不需要ExpandRecursively
就你而言,但我们could使用它...它给出相同的结果:
type ExpandedText = Expand<Text>;
当我们在 IDE(TypeScript Playground 和 VSCode)中将鼠标悬停在它上面时,它会显示为:
/* type ExpandedText = {
name: string;
type: "text";
value: string;
title: string;
start: number;
extras: object;
} */
如你所愿。
链接到代码