【问题标题】:tslint complaining "statements must be filtered with an if statement" when using switch使用 switch 时 tslint 抱怨“必须使用 if 语句过滤语句”
【发布时间】:2017-10-31 05:09:47
【问题描述】:

假设我有以下方法:

getErrorMessage(state: any, thingName?: string) {
    const thing: string = state.path || thingName;
    const messages: string[] = [];
    if (state.errors) {
        for (const errorName in state.errors) {
            switch (errorName) {
                case 'required':
                    messages.push(`You must enter a ${thing}`);
                    break;
                case 'minlength':
                    messages.push(`A ${thing} must be at least ${state.errors['minlength'].requiredLength}characters`);
                    break;
                case 'pattern':
                    messages.push(`The ${thing} contains illegal characters`);
                    break;
                case 'validateCardNumberWithAlgo':
                    messages.push(`Card doesnt pass algo`);
                    break;
            }
        }
    }
    return messages;
}

当我跑步时

ng lint

我收到以下错误:

for (... in ...) 语句必须用 if 语句过滤

查看类似的question 我认为该答案不适用于我的情况。毕竟 switch 语句属于 if-else-if 阶梯的类别。

tslint 应该将 switch 语句视为 if 语句的形式,但事实并非如此?!

【问题讨论】:

  • 使用 if else 代替 switch?
  • 如果我要检查 100 个条件,你会建议同样的事情吗?
  • 我实际上建议您将内部 for 循环重构为其他内容。 :) 方法调用,或者映射错误数组以创建错误消息列表。 :)
  • @toskv 我认为关键是规则说if 语句应该在for...in 之后,而switch 语句可以看作是if 语句的一种,然而它不能解决错误。

标签: angular typescript angular-cli tslint


【解决方案1】:

这让我很好奇,所以我查看了TSlint source code 的这条规则。它有一个名为isFiltered 的函数,它似乎只检查ts.SyntaxKind.IfStatement,而不是ts.SyntaxKind.SwitchStatement

function isFiltered({statements}: ts.Block): boolean {
    switch (statements.length) {
        case 0: return true;
        case 1: return statements[0].kind === ts.SyntaxKind.IfStatement;
        default:
            return statements[0].kind === ts.SyntaxKind.IfStatement && nodeIsContinue((statements[0] as ts.IfStatement).thenStatement);
    }

}

因此,除非您想将对象转换为数组,否则您需要使用您提供的链接中的修复程序。 Object.keysif 声明:

    for (const errorName in state.errors) {
      if (state.errors.hasOwnProperty(errorName)) {
        switch (errorName) {

有趣的是,你可以有任何类型的if 语句,错误就会消失。没有检查您是否正在呼叫hasOwnProperty

【讨论】:

    【解决方案2】:

    该规则旨在防止您在使用 for .. in 时访问对象原型上定义的属性。

    但是,您可以重构代码以使其不使用它,并使其更易于维护和开发。

    一个例子是这样的:

    interface ErrorMessageFactory {
      (thing: string, state?): string
    }
    
    type Errors = 'required' | 'minlength' | 'pattern' | 'validateCardNumberWithAlgo'
    
    let errorFactory: {[e in Errors]: ErrorMessageFactory} = {
      required: (thing) => `You must enter a ${thing}`,
      minlength: (thing, state) => `A ${thing} must be at least ${state.errors['minlength'].requiredLength}characters`,
      pattern: (thing) => `The ${thing} contains illegal characters`,
      validateCardNumberWithAlgo: (thing) => `Card doesnt pass algo`
    }
    
    
    
    function getErrorMessage(state: any, thingName?: string) {
      if (state.errors) {
        return state.errors.map((error) => errorFactory[error](thingName, state));
      }
      return [];
    }
    

    你可以在操场上看到一个工作的 sn-p here

    【讨论】:

      猜你喜欢
      • 2017-04-07
      • 1970-01-01
      • 2012-02-25
      • 2016-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-06
      相关资源
      最近更新 更多