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

“catch”并在条件中显式处理未解析的泛型?

  •  0
  • phry  · 技术社区  · 5 年前

    一段时间以来,我一直在努力寻找一个现实生活中的例子,但并不太复杂。我希望这能奏效。

    我们正在与 immer ,出口a Draft 类型看起来像这样(我简化了一点):

    type Draft<T> = T extends object ?
        {
          -readonly [K in keyof T]:  Draft<T[K]>
        }
      : T
    

    因此,该类型仅删除 readonly 属性,深度嵌套,来自它遇到的所有对象属性。

    这工作得很好,直到 T 是一个尚未解决的泛型。在这种情况下,它会一直存在 Draft<T> 并且不能被赋予以下值 T (考虑到类型,这应该总是可能的)。

    所以我的问题是:我能以某种方式检测到一个类型是未解析的,并返回不同的结果吗?

    本质上,类似

    type Draft<T> = 
        T is unresolved ? 
          T 
        : T extends object ?
        {
          -readonly [K in keyof T]:  Draft<T[K]>
        }
      : T
    

    我准备了一个引发这种行为的例子 as a TypeScript playground .

    在功能之外, T 已解决,一切正常,但在函数内部,我无法按预期调用子函数 草稿<T> 并假设 T a论点不一致。

    是的,这有点做作。如果你想要一个现实生活中的例子,你可以看看 this issue 此外,未解析泛型上的条件类型采用所有可能的形式,因此返回不兼容的函数签名。因此,我们有不止一种情况,我很想找到一个好的答案来避免这种TS行为:(

    0 回复  |  直到 5 年前
        1
  •  1
  •   Pedro Mutter    5 年前

    我无法使用类型定义为您找到解决方案。我试着用 infer keyword 看看我是否能到达某个地方,但什么都没有。 但是,我可以在您使用的方式中找到一个“解决方法” Draft 键入您的示例。我只是宣布一个新的 草稿 由初始化的变量 initialParam 通过打字 草稿 类型。

    function genericFn<T>(initialParam: Data<T>) { 
      function test(param: Draft<Data<T>>) { 
        // ...
      }
    
      const draft: Draft<Data<T>> = initialParam as Draft<Data<T>>;
      test(draft);
      return test;
    }
    

    希望它对你有用。这不是最优雅的解决方案,但它阻止了Typescript错误。