Search code examples
angulartypescripttslint

ng lint returning false errors Angular 8


Out of nowhere when I run ng lint, I get all these false errors

Forbidden 'var' keyword, use 'let' or 'const' instead

but I know for a fact that I am not using var anywhere in these files, also when I run ng lint --fix It replaces the exp in export and fun in function with let so export function becomes letport letction

I have no Idea how this started happening or why this started happening

this is my tslint file

{
    "rulesDirectory": ["node_modules/codelyzer"],
    "rules": {
        "arrow-return-shorthand": true,
        "callable-types": true,
        "class-name": true,
        "comment-format": [true],
        "curly": true,
        "eofline": true,
        "forin": true,
        "import-blacklist": [true],
        "import-spacing": true,
        "interface-over-type-literal": true,
        "label-position": true,
        "max-line-length": [false],
        "member-access": false,
        "member-ordering": [
            true,
            {
                "order": ["static-field", "instance-field", "static-method", "instance-method"]
            }
        ],
        "no-arg": true,
        "no-bitwise": true,
        "no-console": [true, "debug", "info", "time", "timeEnd", "trace"],
        "no-construct": true,
        "no-debugger": true,
        "no-duplicate-super": true,
        "no-empty": false,
        "no-empty-interface": true,
        "no-eval": false,
        "no-inferrable-types": [true, "ignore-params"],
        "no-misused-new": true,
        "no-non-null-assertion": true,
        "no-shadowed-variable": false,
        "no-string-literal": false,
        "no-string-throw": true,
        "no-switch-case-fall-through": true,
        "no-trailing-whitespace": true,
        "no-unnecessary-initializer": true,
        "no-unused-expression": false,
        "no-var-keyword": true,
        "object-literal-sort-keys": false,
        "one-line": [true, "check-open-brace", "check-catch", "check-else", "check-whitespace"],
        "prefer-const": false,
        "quotemark": [true, "single"],
        "radix": false,
        "semicolon": [true, "always"],
        "triple-equals": [true, "allow-null-check"],
        "typedef-whitespace": [
            true,
            {
                "call-signature": "nospace",
                "index-signature": "nospace",
                "parameter": "nospace",
                "property-declaration": "nospace",
                "variable-declaration": "nospace"
            }
        ],
        "unified-signatures": true,
        "variable-name": false,
        "whitespace": [true, "check-branch", "check-decl", "check-operator", "check-separator", "check-type"],
        "directive-selector": [false, "attribute", "app", "camelCase"],
        "component-selector": [false, "element", "app", "kebab-case"],
        "no-input-rename": true,
        "no-output-rename": true,
        "use-life-cycle-interface": true,
        "use-pipe-transform-interface": true,
        "component-class-suffix": true,
        "directive-class-suffix": true,
        "no-access-missing-member": false
    }
}

and in my package.json

"typescript": "3.4.5",
"codelyzer": "^5.1.0",
"tslint": "5.17.0",

I also seem to be getting heaps of warnings like

The 'no-arg' rule threw an error in '/angular/src/shared/helpers/FormattedStringValueExtracter.ts':

and this is that file

class ExtractionResult {
    public IsMatch: boolean;
    public Matches: any[];

    constructor(isMatch: boolean) {
        this.IsMatch = isMatch;
        this.Matches = [];
    }
}

enum FormatStringTokenType {
    ConstantText,
    DynamicValue
}

class FormatStringToken {
    public Text: string;

    public Type: FormatStringTokenType;

    constructor(text: string, type: FormatStringTokenType) {
        this.Text = text;
        this.Type = type;
    }
}

class FormatStringTokenizer {
    Tokenize(format: string, includeBracketsForDynamicValues: boolean = false): FormatStringToken[] {
        const tokens: FormatStringToken[] = [];

        let currentText = '';
        let inDynamicValue = false;

        for (let i = 0; i < format.length; i++) {
            const c = format[i];
            switch (c) {
                case '{':
                    if (inDynamicValue) {
                        throw new Error(
                            'Incorrect syntax at char ' + i + '! format string can not contain nested dynamic value expression!'
                        );
                    }

                    inDynamicValue = true;

                    if (currentText.length > 0) {
                        tokens.push(new FormatStringToken(currentText, FormatStringTokenType.ConstantText));
                        currentText = '';
                    }

                    break;
                case '}':
                    if (!inDynamicValue) {
                        throw new Error(
                            'Incorrect syntax at char ' + i + '! These is no opening brackets for the closing bracket }.'
                        );
                    }

                    inDynamicValue = false;

                    if (currentText.length <= 0) {
                        throw new Error('Incorrect syntax at char ' + i + '! Brackets does not containt any chars.');
                    }

                    let dynamicValue = currentText;
                    if (includeBracketsForDynamicValues) {
                        dynamicValue = '{' + dynamicValue + '}';
                    }

                    tokens.push(new FormatStringToken(dynamicValue, FormatStringTokenType.DynamicValue));
                    currentText = '';

                    break;
                default:
                    currentText += c;
                    break;
            }
        }

        if (inDynamicValue) {
            throw new Error('There is no closing } char for an opened { char.');
        }

        if (currentText.length > 0) {
            tokens.push(new FormatStringToken(currentText, FormatStringTokenType.ConstantText));
        }

        return tokens;
    }
}

export class FormattedStringValueExtracter {
    Extract(str: string, format: string): ExtractionResult {
        if (str === format) {
            return new ExtractionResult(true);
        }

        const formatTokens = new FormatStringTokenizer().Tokenize(format);
        if (!formatTokens) {
            return new ExtractionResult(str === '');
        }

        const result = new ExtractionResult(true);

        for (let i = 0; i < formatTokens.length; i++) {
            const currentToken = formatTokens[i];
            const previousToken = i > 0 ? formatTokens[i - 1] : null;

            if (currentToken.Type === FormatStringTokenType.ConstantText) {
                if (i === 0) {
                    if (str.indexOf(currentToken.Text) !== 0) {
                        result.IsMatch = false;
                        return result;
                    }

                    str = str.substr(currentToken.Text.length, str.length - currentToken.Text.length);
                } else {
                    const matchIndex = str.indexOf(currentToken.Text);
                    if (matchIndex < 0) {
                        result.IsMatch = false;
                        return result;
                    }

                    result.Matches.push({ name: previousToken.Text, value: str.substr(0, matchIndex) });
                    str = str.substring(0, matchIndex + currentToken.Text.length);
                }
            }
        }

        const lastToken = formatTokens[formatTokens.length - 1];
        if (lastToken.Type === FormatStringTokenType.DynamicValue) {
            result.Matches.push({ name: lastToken.Text, value: str });
        }

        return result;
    }

    IsMatch(str: string, format: string): string[] {
        const result = new FormattedStringValueExtracter().Extract(str, format);
        if (!result.IsMatch) {
            return [];
        }

        const values = [];
        for (let i = 0; i < result.Matches.length; i++) {
            values.push(result.Matches[i].value);
        }

        return values;
    }
}

When I view any of the files that it says it has issues with, there are no warnings or errors... and when I actually but var in a file it no longer gives me any warnings.. in the problem panel in VSCODE

any help would be appreciated!! Seriously can't figure this one out!

EDIT

I'm also seeing errors like

TypeError: Cannot read property 'pos' of undefined
    at cb (/node_modules/tslint/lib/rules/oneLineRule.js

like theres something wrong with tslint???

EDIT

This is my angular version

Angular CLI: 8.1.2
Node: 10.16.0OS: linux x64
Angular: 8.1.2
... animations, cli, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, platform-server 
... router, service-worker

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.800.6
@angular-devkit/build-angular     0.800.6
@angular-devkit/build-optimizer   0.800.6
@angular-devkit/build-webpack     0.800.6
@angular-devkit/core              8.1.2
@angular-devkit/schematics        7.3.9
@angular/cdk                      7.3.7
@angular/http                     7.2.15
@angular/pwa                      0.12.4
@ngtools/webpack                  8.0.6
@schematics/angular               7.2.4
@schematics/update                0.801.2
rxjs                              6.5.2
typescript                        3.4.5

Solution

  • I started a new local project using the latest version of the CLI and framework (v8.2.0), then added your file in as is. Running npm run lint only gave me one linting error

    ERROR: /<...>/file.ts:145:9 - Expected a 'for-of' loop instead of a 'for' loop with this simple iteration

    So perhaps the issues your having might be solved by updating the cli/framework version. If not then perhaps check your angular.json file to make sure your project is using the ts config that you expect, this was in mine from the default installation

    "lint": {
      "builder": "@angular-devkit/build-angular:tslint",
      "options": {
        "tsConfig": [
          "tsconfig.app.json",
          "tsconfig.spec.json",
          "e2e/tsconfig.json"
        ],
        "exclude": [
          "**/node_modules/**"
        ]
      }
    }