【问题标题】:Object is possibly null. TypeScript error对象可能为空。打字稿错误
【发布时间】:2020-11-07 13:28:51
【问题描述】:

如何修复 ESLint 错误:“对象可能为空”? 在我的代码中,我正在检查 null,但无论如何都有错误

if (controlInput !== null) {
  if (controlInput.match(/[$;.,'"-=!@#$%^&*()]/g).length !== 0) {
    return 'some message'
  }
}

【问题讨论】:

    标签: typescript eslint


    【解决方案1】:

    错误消息不是关于controlInput,而是关于controlInput.match()返回的值。

    如果controlInput 的值与正则表达式匹配,则为Array;如果不匹配,则为null

    常见的解决方案是将controlInput.match()返回的值提取到一个变量中,然后仅当它不是null时才使用它。

    if (controlInput !== null) {
      const matches = controlInput.match(/[$;.,'"-=!@#$%^&*()]/g);
      if (matches && matches.length) {
        return 'some message';
      }
    }
    

    但是如果您不关心匹配的子字符串,而仅当字符串与正则表达式匹配时,您可以直接检查controInput.match()返回的值:

    if (controlInput !== null && controlInput.match(/[$;.,'"-=!@#$%^&*()]/g)) {
      return 'some message';
    }
    

    或者,更好的是,使用RegExp.test()。它更快。

    if (controlInput !== null && /[$;.,'"-=!@#$%^&*()]/.test(controlInput)) {
      return 'some message';
    }
    

    关于正则表达式的一些想法

    显然您想检查controlInput 的值是否包含一些特殊字符。

    regexp 中,表达式[...] 称为"character set",它匹配方括号之间指定的字符列表中的一个字符。

    大多数字符在字符集中表示自己。但是,字符集中有两个特殊字符。其中一个是^,但前提是它是字符集中的第一个字符(紧跟在[ 之后)。它否定了字符集的含义。

    另一个特殊字符是-,当它不是字符集中的第一个或最后一个字符时。 [a-z] 不是指“a-z 之一”,而是“介于 az 之间的任何字符”,即任何小写字母。

    正则表达式中的字符类包含片段"-=,该片段在字符集中匹配"ASCII code 中的"= 之间的所有字符。此子集包括.,; 和您已包含在字符集中的其他字符。

    这就是为什么我认为您的意图不是包括 "= 之间的所有字符,而只包括字符 "-=

    为了获得预期的行为(- 代表自己)在集合的开头或结尾移动-

    if (controlInput !== null && /[-$;.,'"=!@#$%^&*()]/.test(controlInput)) {
      return 'some message';
    }
    

    【讨论】:

      【解决方案2】:

      问题在于match() 方法的返回类型为RegExpMatchArray | null。所以match()的返回值可能是null,也就是正则表达式不匹配字符串的时候。而null.length 会在运行时引发错误。

      您可以通过不检查长度来解决此问题。 match() 方法将在不匹配时返回 null,或者在匹配时返回包含至少一个字符串的数组。这意味着您可以直接在条件中使用match() 的结果:

      if (controlInput.match(/[$;.,'"-=!@#$%^&*()]/g)) {
        return 'some message'
      }
      

      Playground

      【讨论】:

        【解决方案3】:

        实现您想要的最简单的方法是使用optional chaining? 运算符):

        if(controlInput?.match(/[$;.,'"-=!@#$%^&*()]/g)?.length !== 0) {
          return 'some message'
        }
        

        这样就达到了和写一样的效果:

        if (controlInput !== null) {
          const matches = controlInput.match(/[$;.,'"-=!@#$%^&*()]/g)
        
          if (matches && matches.length !== 0) {
            return 'some message'
          }
        }
        

        【讨论】:

        • 现在我在这一行出现错误controlInput.match(/[$;.,'"-=!@#$%^&*()]/g).length !== 0
        • 我重写了第二个代码块,你可以试试吗?
        【解决方案4】:

        根据您使用的打字稿版本,您可以使用可选的链接运算符(请参阅接受的答案Does Typescript support the ?. operator? (And, what's it called?)

        if (controlInput?.match(/[$;.,'"-=!@#$%^&*()]/g).length !== 0) {
            return 'some message' 
          }
        

        添加错误消息和错误位置会很有帮助,因为我猜测问题出在哪里。

        另外,如果你使用的是旧版本的打字稿,你总是可以有一个 if check like...

        if (controlInput
            && controlInput.match(/[$;.,'"-=!@#$%^&*()]/g).length !== 0
        ) {
          return 'some message' 
        }
        

        【讨论】:

        • 这个不行。我不知道这里出了什么问题
        猜你喜欢
        • 1970-01-01
        • 2019-09-04
        • 2022-01-08
        • 1970-01-01
        • 2023-01-20
        • 2017-10-12
        • 2019-05-12
        • 2022-01-26
        • 1970-01-01
        相关资源
        最近更新 更多