【问题标题】:custom tslint rule to catch "=== undefined" not working自定义 tslint 规则来捕获“=== undefined”不起作用
【发布时间】:2018-12-31 13:54:03
【问题描述】:

我已将 this tslint rule 复制到我的项目中并使其正常工作,因此现在 tslint 会选择任何 === null 并使其出错。

我现在想做同样的事情,只是为了undefined。我已经实现了与null 相同的实现,但是将检查更改为查找ts.SyntaxKind.UndefinedKeyWord 而不是ts.SyntaxKind.NullKeyword,并且由于某种原因它没有选择=== undefined

如果它与正在工作的null 相同,为什么不呢?

noTripleEqualsNullRule.ts

import * as ts from "typescript";
import * as Lint from "tslint";

const OPTION_NO_NULL_KEYWORD = "no-null-keyword";

export class Rule extends Lint.Rules.AbstractRule {
    public static EQ_FAILURE_STRING = "Did you mean == null instead?";
    public static NEQ_FAILURE_STRING = "Did you mean != null instead?";

    public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
        const noTripleEqualsNullWalker = new NoTripleEqualsNullWalker(sourceFile, this.getOptions());
        return this.applyWithWalker(noTripleEqualsNullWalker);
    }
}

class NoTripleEqualsNullWalker extends Lint.RuleWalker {
    public visitBinaryExpression(node: ts.BinaryExpression) {
        if (this.isExpressionAllowed(node)) {
            const position = node.getChildAt(1).getStart();
            const expressionWidth = node.right.getFullWidth() + 3;
            this.handleBinaryComparison(position, expressionWidth, node.operatorToken.kind, node.right.kind);
        }

        super.visitBinaryExpression(node);
    }

    private handleBinaryComparison(position: number, expressionWidth: number, operator: ts.SyntaxKind, right: ts.SyntaxKind) {
        switch (operator) {
            case ts.SyntaxKind.EqualsEqualsEqualsToken:
                if (right === ts.SyntaxKind.NullKeyword) {
                    this.addFailure(this.createFailure(position, expressionWidth, Rule.EQ_FAILURE_STRING));
                }
                break;
            case ts.SyntaxKind.ExclamationEqualsEqualsToken:
                if (right === ts.SyntaxKind.NullKeyword) {
                    this.addFailure(this.createFailure(position, expressionWidth, Rule.NEQ_FAILURE_STRING));
                }
                break;
            default:
                break;
        }
    }

    private isExpressionAllowed(node: ts.BinaryExpression) {
        const nullKeyword = ts.SyntaxKind.NullKeyword;

        return !this.hasOption(OPTION_NO_NULL_KEYWORD)
            && (node.left.kind ===  nullKeyword || node.right.kind === nullKeyword);
    }
}

noTripleEqualsUndefinedRule.ts

import * as ts from "typescript";
import * as Lint from "tslint";

const OPTION_NO_NULL_KEYWORD = "no-null-keyword";

export class Rule extends Lint.Rules.AbstractRule {
    public static EQ_FAILURE_STRING = "Did you mean == null instead?";
    public static NEQ_FAILURE_STRING = "Did you mean != null instead?";

    public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
        const noTripleEqualsNullWalker = new NoTripleEqualsNullWalker(sourceFile, this.getOptions());
        return this.applyWithWalker(noTripleEqualsNullWalker);
    }
}

class NoTripleEqualsNullWalker extends Lint.RuleWalker {
    public visitBinaryExpression(node: ts.BinaryExpression) {
        if (this.isExpressionAllowed(node)) {
            const position = node.getChildAt(1).getStart();
            const expressionWidth = node.right.getFullWidth() + 3;
            this.handleBinaryComparison(position, expressionWidth, node.operatorToken.kind, node.right.kind);
        }

        super.visitBinaryExpression(node);
    }

    private handleBinaryComparison(position: number, expressionWidth: number, operator: ts.SyntaxKind, right: ts.SyntaxKind) {
        switch (operator) {
            case ts.SyntaxKind.EqualsEqualsEqualsToken:
                if (right === ts.SyntaxKind.UndefinedKeyword) {
                    this.addFailure(this.createFailure(position, expressionWidth, Rule.EQ_FAILURE_STRING));
                }
                break;
            case ts.SyntaxKind.ExclamationEqualsEqualsToken:
                if (right === ts.SyntaxKind.UndefinedKeyword) {
                    this.addFailure(this.createFailure(position, expressionWidth, Rule.NEQ_FAILURE_STRING));
                }
                break;
            default:
                break;
        }
    }

    private isExpressionAllowed(node: ts.BinaryExpression) {
        const nullKeyword = ts.SyntaxKind.UndefinedKeyword;

        return !this.hasOption(OPTION_NO_NULL_KEYWORD)
            && (node.left.kind ===  nullKeyword || node.right.kind === nullKeyword);
    }
}

【问题讨论】:

标签: typescript tslint


【解决方案1】:

linter 认为undefined 的类型是SyntaxKind.Identifier 而不是SyntaxKind.UndefinedKeyword。这种是有道理的,因为 undefined 可以重新定义——但仍然很不幸。

如果您确定 undefined 没有在您的代码库中的任何地方重新定义,您可以改为检查 node.getText() === "undefined"

【讨论】:

    猜你喜欢
    • 2016-02-04
    • 1970-01-01
    • 2017-03-10
    • 2019-03-12
    • 2015-12-26
    • 2015-01-31
    • 1970-01-01
    • 2019-11-30
    • 2015-03-12
    相关资源
    最近更新 更多