TypeScript 中的递归泛型

Recursive Generics in TypeScript

我想声明一个简单的类型来替换一段代码中的 any。我知道这将是一些对象式的论点,所以我可以使用 Record<string, unknown>,但我宁愿成为一个更具体的 little

这将是理想的:

type MyObject = Record<string, string | string[] | number | boolean | MyObject>

但它给出了错误

Type alias 'MyObject' circularly references itself.ts(2456)

我可以通过接口作弊来解决这个问题:

type MyObject<T> = Record<string, string | string[] | number | boolean | T>

// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface IMyObject extends MyObject<IMyObject>{}

有没有办法做我想做的事,还是我应该坚持Record<string, unknown>

编译器在意识到您指定的类型以受支持的方式递归之前就放弃了,因为它没有探查 the Record utility type before checking for circularity. This is a design limitation of TypeScript. See microsoft/TypeScript#41164 的定义以获得解释。

此处的解决方法是将 Record<string, XYZ> 替换为它最终变成的内容,一种带有字符串 index signature 的类型,例如 { [k: string]: XYZ }:

type MyObject = 
  { [k: string]: string | string[] | number | boolean | MyObject } // okay

可以正常工作。

Playground link to code

您不需要将其设为通用

type MyObject = Record<string, string | string[] | number | boolean | IMyObject>
interface IMyObject extends MyObject {}