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

在Typescript中,从本可以未定义的字典中获取记录时,是否应该使用类型断言?

  •  0
  • Tom  · 技术社区  · 8 年前

    字典通常用于通过字符串标识符有效地测试元素是否存在。如果结果是 undefined 它不存在。内存缓存就是一个很好的例子:

    /**
     * Cache of normalized data
     */
    export interface IDataNormalizationsCache
      extends Record<NormalizationMethod, ILeanTrainingData | undefined> {}
    
    /**
     * A dictionary which caches all performed varieties of data normalizations.
     */
    const dataNormalizations: IDataNormalizationsCache = {
      [NormalizationMethod.log]: undefined
    }
    

    然后我们可以从缓存中检索此数据:

    // Retrieve from cache
    if (typeof dataNormalizations[method] !== 'undefined') {
      return dataNormalizations[method]
    }
    

    然而,即使 dataNormalizations[method] 保证在此时定义,因此类型为 ILeanTrainingData ,Typescript引发编译错误:

    [ts]
    Type 'ILeanTrainingData | undefined' is not assignable to type 'ILeanTrainingData'.
      Type 'undefined' is not assignable to type 'ILeanTrainingData'.
    

    为什么编译器不识别 typeof undefined 测试?

    有没有比使用类型断言更好的方法,例如:

    // Retrieve from cache
    if (typeof dataNormalizations[method] !== 'undefined') {
      return dataNormalizations[method] as ILeanTrainingData
    }
    
    1 回复  |  直到 8 年前
        1
  •  3
  •   jcalz    8 年前

    这是一个可悲的结果 an outstanding issue in TypeScript 通过括号符号进行属性访问不会像使用点符号那样触发类型保护。显然,将check for bracket符号添加到编译器中是很简单的,但是它会导致明显更长的编译时间。

    我假设您在编译时不知道属性名的实际字符串文字。。。否则我建议使用点符号:

    if (typeof dataNormalizations.knownMethod !== 'undefined') {
      return dataNormalizations.knownMethod; // works
    }
    

    它会起作用的。但你可能做不到。在这种情况下,更好的解决方法是将属性分配给新变量:

    const dataNormalizationsMethod = dataNormalizations[method];
    if (typeof dataNormalizationsMethod !== 'undefined') {
      return dataNormalizationsMethod; // works
    }
    

    它还允许类型保护工作,因为它不再进行属性访问。

    在我看来,你的类型断言也很好。

    希望能有所帮助。祝你好运!

    推荐文章