【问题标题】:How to fix error in lookup type for typescript?如何修复打字稿查找类型中的错误?
【发布时间】:2020-06-09 12:24:29
【问题描述】:

我的问题:我的问题的一个最小示例是 (typescript play example with the code):

enum Keys { foo = "foo", bar = "bar" }

function getValue<A extends Keys, B>(dict: { [K in A]?: B }, key: A): B | null
{
    const result = dict[key]

    if (result !== undefined) {
        return result
    } else {
        return null
    }
}

Typescript 对语句 return result 给出以下类型检查错误:

Type 'B | undefined' is not assignable to type 'B | null'.
  Type 'undefined' is not assignable to type 'B | null'.

我的问题:为什么类型保护result !== undefined 在上面的示例中不起作用,我该如何解决?

我的尝试:

  • 当我检查https://www.typescriptlang.org/play/index.html 中的示例时,我看到变量result 的类型为{ [K in A]?: B | undefined; }[A]。但是我预计打字稿可以自动将其减少到B | undefined。也许我在Adict 的类型声明中有错误,因此打字稿无法减少查找类型...
  • 当前的夜间版本3.9.0-dev.20200224也会出现该错误。
  • 将类型保护更改为typeof(result) !== "undefined" 没有帮助。

【问题讨论】:

    标签: typescript dictionary types type-conversion lookup


    【解决方案1】:

    目前这似乎是 TSC 的错误或设计限制。它不能立即将{ [K in A]?: B | undefined; }[A] 减少到B | undefined,因此您可以将结果转换为B | undefined 或将Keys 移出通用

    const enum Keys { foo = "foo", bar = "bar" }
    
    function get<B>(
        dict: { [K in Keys]?: B },
        key: Keys
    ): B | null {
        const result = dict[key]
    
        if (result !== undefined) {
            return result
        } else {
            return null
        }
    }
    

    我也建议始终使用 const enum

    【讨论】:

      【解决方案2】:

      我的问题:上述代码示例中的错误是什么,我该如何解决?看来类型保护结果 !== undefined 不起作用...

      “修复”它的一种方法是始终返回undefined,而不是返回null。以下作为 API 工作,但正如 @Austaras 正确所说,它不能有效地将类型保护内的 result 缩小到 B

      function getValueOne<A extends Keys, B>(
          dict: { [K in A]?: B },
          key: A
      ): B | undefined {
          const result = dict[key]
      
          if (result !== undefined) {
              return result; // result is { [K in A]?: B | undefined; }[A]
          } else {
              return undefined;
          }
      }
      

      另一种“修复”它的方法是使用这样的显式类型:

      function getValueToo<A extends Keys, B>(
          dict: { [K in A]?: B },
          key: A
      ): B | null {
          const result: B | undefined = dict[key];
      
          if (result) {
              return result; // result is B
          } else {
              return null;
          }
      }
      

      这第三种方法可能是我最喜欢的,因为它是三种方法中最通用的。我们更改返回类型。

      function getValueThree<A extends Keys, B>(
          dict: { [K in A]?: B },
          key: A
      ): (typeof dict)[A] {
          const result = dict[key]
      
          if (result !== undefined) {
              return result;
          } else {
              return undefined;
          }
      }
      

      All three are in the playground.

      【讨论】:

        猜你喜欢
        • 2022-10-30
        • 2022-08-06
        • 2018-03-21
        • 1970-01-01
        • 2019-05-13
        • 1970-01-01
        • 2022-01-26
        • 2018-12-17
        • 2020-09-20
        相关资源
        最近更新 更多