代码之家  ›  专栏  ›  技术社区  ›  HaveSpacesuit

TypeScript中的递归泛型

  •  1
  • HaveSpacesuit  · 技术社区  · 3 年前

    我想声明一个简单的类型来替换 any 在一段代码中。我知道这将是一个客观的论点,所以我可以使用 Record<string, unknown> ,但我宁愿当 小的 更具体地说。

    这将是理想的:

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

    但它给出了错误

    类型别名“MyObject”循环引用自身.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>{}
    

    有没有办法做我想做的事,还是我应该坚持下去 记录<字符串,未知> ?

    1 回复  |  直到 3 年前
        1
  •  8
  •   jcalz    3 年前

    编译器在意识到您指定的类型是以支持的方式递归之前就放弃了,因为它没有探测 the Record utility type 在检查圆形度之前。这是TypeScript的设计限制。请参阅 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

        2
  •  1
  •   Mark Swardstrom    3 年前

    你不需要把它变成通用的

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