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

类型“null”必须具有“[Symbol.iterator]”方法

  •  0
  • Ilja  · 技术社区  · 6 年前

    我在下面有一个函数,它接受数值并将其解析为11k、1m等货币值。。。它完成了任务,但我在这条线上收到ts错误:

    const [match] = `${value / divider}`.match(regx);
    

    类型“null”必须具有返回 iterator.ts(2488)

    完整代码

    export function getCurrencyValue(value: number) {
      const ranges = [{ divider: 1e6, suffix: 'm' }, { divider: 1e3, suffix: 'k' }];
      const regx = new RegExp('^-?\\d+(?:.\\d{0,1})?');
      let formatedValue = '';
    
      ranges.forEach(range => {
        const { divider, suffix } = range;
    
        if (value >= divider) {
          const [match] = `${value / divider}`.match(regx);
    
          if (match) {
            formatedValue = `${match}${suffix}`;
          }
        }
      });
    
      return formatedValue || value;
    }
    
    1 回复  |  直到 6 年前
        1
  •  7
  •   T.J. Crowder    6 年前

    你不能破坏结构 null 所以

    const [match] = `${value / divider}`.match(regx);
    

    match 当没有对手的时候。您需要将其拆分为两个语句,或者使用 || [] 诡计或类似的。看看您的完整代码,这里的解构似乎没有帮助(因为可能 无效的 ),简单来说:

    const match = `${value / divider}`.match(regx);
    
    if (match) {
      formatedValue = `${match[0]}${suffix}`;
    }
    

    错误消息之所以会这么说,是因为您正在进行的(使用 [] )依赖于从正在分解的对象中获取迭代器(分解的结果) ).通过使用它的 Symbol.iterator 方法:

    const it = `${value / divider}`.match(regx)[Symbol.iterator]();
    

    火柴 你能回来吗 无效的 无效的 Symbol.iterator 属性,TypeScript对此表示不满。


    旁注: forEach 在这里似乎不是合适的工具,因为你想在第一次得到匹配时停止。现在,你要写信给我 formattedValue 对于 1e6 范围,然后用格式化的结果覆盖它 1e3 范围

    for-of 是个不错的选择:

    export function getCurrencyValue(value: number) {
      const ranges = [{ divider: 1e6, suffix: 'm' }, { divider: 1e3, suffix: 'k' }];
      const regx = new RegExp('^-?\\d+(?:.\\d{0,1})?');
    
      for (const { divider, suffix } of ranges) {
        if (value >= divider) {
          const match = `${value / divider}`.match(regx);
          if (match) {
            return `${match[0]}${suffix}`;
          }
        }
      });
    
      return String(value); // Presumably you always want it to be a string
    }
    

    为了清晰起见,我可能还会使用文本正则表达式语法(不必使用双转义反斜杠),并移动 ranges regx 在函数外部,因此它们不会每次都被重新创建(因为这是在一个模块中,并且是单独创建的,因为正则表达式没有 g y 旗帜):

    const ranges = [{ divider: 1e6, suffix: 'm' }, { divider: 1e3, suffix: 'k' }];
    const regx = /^-?\d+(?:.\d{0,1})?/;
    export function getCurrencyValue(value: number) {
    
      for (const { divider, suffix } of ranges) {
        if (value >= divider) {
          const match = `${value / divider}`.match(regx);
          if (match) {
            return `${match[0]}${suffix}`;
          }
        }
      });
    
      return String(value); // Presumably you always want it to be a string
    }
    

    为了 在您的环境中,因为您正在传输到ES5,并且不允许依赖于再生器运行时。所以不是 弗雷奇 ,你会想要的 some :

    const ranges = [{ divider: 1e6, suffix: 'm' }, { divider: 1e3, suffix: 'k' }];
    const regx = /^-?\d+(?:.\d{0,1})?/;
    export function getCurrencyValue(value: number) {
      let formattedValue = String(value); // Presumably you want it to always be a string
    
      // Not allowed to use for-of, and the rule saying not to use it also doesn't like `for` loops, so...
      ranges.some(({ divider, suffix }) => {
        if (value >= divider) {
          const match = `${value / divider}`.match(regx);
          if (match) {
            formattedValue = `${match[0]}${suffix}`;
            return true;
          }
        }
        return false;
      });
    
      return formattedValue;
    }
    

    或与 reduce :

    const ranges = [{ divider: 1e6, suffix: 'm' }, { divider: 1e3, suffix: 'k' }];
    const regx = /^-?\d+(?:.\d{0,1})?/;
    export function getCurrencyValue(value: number) {
    
      // Not allowed to use for-of, and the rule saying not to use it also doesn't like `for` loops, so...
      return ranges.reduce((formattedValue, { divider, suffix }) => {
        if (value >= divider) {
          const match = `${value / divider}`.match(regx);
          if (match) {
            formattedValue = `${match[0]}${suffix}`;
          }
        }
        return formattedValue;
      }, String(value)); // Presumably you always want it to be a string
    }