打字稿无限递归推理
检查我在某处找到的这个打字稿 4.2 片段(此处为游乐场):
type BlackMagic<T> = { [K in keyof T]: BlackMagic<T[K]> }
declare const foo: BlackMagic<{q: string}>;
declare const str: BlackMagic<string>;
declare const num: BlackMagic<12>;
我无法绕过它。TS 如何处理?怎么不陷入无限递归?具体来说,在strand的情况下num,将鼠标悬停在变量上表明 TS 正在将类型解析为 just stringand 12。怎么会这样?
回答
如果您的类型包含BlackMagic<T> 相同的T类型,您将陷入无限递归,但在这里我们将实用程序类型BlackMagic应用于不同的值T[K]。
type BlackMagic<T> = { [K in keyof T]: BlackMagic<T[K]> }
这种类型表示这BlackMagic<T>是一个object,其中键是 的键,T值是 的值的BlackMagic映射版本T。
该BlackMagic类型在您的示例str和num.
IfT是原始类型而不是objectthenBlackMagic<T>只是T它本身。这是一个标准的行为程序类型被映射的类型。例如Partial<12>只是12. 此行为在非错误的常见问题常见“错误”中进行了解释
映射类型声明为
{ [ K in keyof T ]: U }其中T是参数被称为同态映射的类型,这意味着映射类型是保存的功能的结构的类型T。当T使用原始类型实例化类型参数时,映射类型计算为相同的原始类型。
foo: BlackMagic<{q: string}>实际上会做一些映射,但它只有一层深。 BlackMagic<{q: string}>变成{q: BlackMagic<string>}. 我们刚刚看到的BlackMagic<string>是string,所以接下来的类型变成了{q: string}.