Tslint: TypeError: Cannot read property 'kind' of undefined: ObjectLiteralShorthandRule

Created on 29 Nov 2017  路  8Comments  路  Source: palantir/tslint

Bug Report

  • __TSLint version__: 5.8.0
  • __TypeScript version__: 2.6.2
  • __Running TSLint via__: (pick one) angular-cli v.1.5.4: ng lint --format=stylish

_Seems_ to fail at this line: https://github.com/palantir/tslint/blob/master/src/rules/objectLiteralShorthandRule.ts#L86

TypeScript code being linted

// code snippet
?

with tslint.json configuration:

{
  "extends": [
    "tslint:recommended",
    "tslint-immutable",
    "tslint-consistent-codestyle",
    "tslint-microsoft-contrib",
    "codelyzer",
    "tslint-config-prettier"
  ],
  "rulesDirectory": "node_modules/codelyzer",
  "project": "./tsconfig.json",
  "exclude": [
    "**/src/**/*.ts",
    "**/e2e/**",
    "**/node_modules/**/*",
    "**/coverage/**/*"
  ],
  "format": "stylish",
  "rules": {
    "object-literal-sort-keys": false,
    "ordered-imports": false,
    "member-access": false,
    "member-ordering": false,
    "no-string-literal": false,
    "radix": false,
    "no-angle-bracket-type-assertion": false,
    "no-as-type-assertion": true,
    "no-empty": false,
    "array-type": false,
    "typedef": [
      true,
      "parameter",
      "property-declaration",
      "object-destructuring",
      "array-destructuring",
      "call-signature"
    ],
    "no-var-keyword": true,
    "no-parameter-reassignment": true,
    "readonly-array": true,
    "no-mixed-interface": true,
    "insecure-random": true,
    "no-banned-terms": true,
    "no-empty-interface": true,
    "no-useless-files": true,
    "possible-timing-attack": true,
    "valid-typeof": true,
    "use-named-parameter": true,
    "arrow-return-shorthand": [true, "multiline"],
    "triple-equals": true,
    "no-unnecessary-initializer": true,
    "no-var-before-return": true,
    "no-unnecessary-qualifier": true,
    "no-unnecessary-callback-wrapper": true,
    "prefer-const": true,
    "object-literal-shorthand": true,
    "prefer-template": true,
    "no-non-null-assertion": true,
    "await-promise": true,
    "no-conditional-assignment": true,
    "no-construct": true,
    "no-for-in-array": true,
    "no-misused-new": true,
    "promise-function-async": true,
    "no-unused-expression": true,
    "no-unused-variable": true,
    "no-object-literal-type-assertion": true,
    "deprecation": true,
    "no-accessor-recursion": true,
    "no-return-undefined": true,
    "no-static-this": true,
    "prefer-while": true,
    "prefer-const-enum": true,
    "no-function-expression": true,
    "parameter-properties": [true, "all-or-none"],
    "cyclomatic-complexity": true,
    "directive-selector": [
      true,
      "attribute",
      ["dir-prefix1", "dir-prefix2"],
      "camelCase"
    ],
    "component-selector": [true, "element", "cng", "kebab-case"],
    "angular-whitespace": [true, "check-interpolation", "check-semicolon"],
    "use-input-property-decorator": true,
    "use-output-property-decorator": true,
    "use-host-property-decorator": true,
    "no-attribute-parameter-decorator": true,
    "no-input-rename": true,
    "no-output-on-prefix": true,
    "no-output-rename": true,
    "no-forward-ref": true,
    "use-life-cycle-interface": true,
    "use-pipe-transform-interface": true,
    "component-class-suffix": [true, "Component"],
    "directive-class-suffix": [true, "Directive"],

    "no-invalid-this": false,
    "underscore-consistent-invocation": false,
    "no-parameter-properties": false,
    "no-multiline-string": false,
    "no-void-expression": false,
    "variable-name": false,
    "function-name": false,
    "newline-before-return": false,
    "missing-jsdoc": false,
    "export-name": false,
    "completed-docs": false,
    "no-relative-imports": false,
    "no-stateless-class": false,
    "restrict-plus-operands": false,
    "no-increment-decrement": false,
    "mocha-no-side-effect-code": false,
    "no-floating-promises": false,
    "strict-boolean-expressions": false,
    "no-backbone-get-set-outside-model": false,
    "no-any": false,
    "no-import-side-effect": false,
    "no-unsafe-any": false,
    "no-http-string": [
      false,
      "http://www.example.com/?.*",
      "http://www.examples.com/?.*"
    ],
    "no-reserved-keywords": false,
    "early-exit": false,
    "no-unused": false,
    "readonly-keyword": false,
    "no-else-after-return": false,
    "no-collapsible-if": false,
    "no-unnecessary-else": false,
    "no-object-mutation": false,
    "no-magic-numbers": false,
    "no-let": false,
    "no-expression-statement": false,
    "no-this": false,
    "no-class": false
  }
}

Actual behavior

TypeError: Cannot read property 'kind' of undefined
    at cb ($MY_PROJECT/node_modules/tslint/lib/rules/objectLiteralShorthandRule.js:69:26)
    at visitNodes ($MY_PROJECT/node_modules/typescript/lib/typescript.js:12699:30)
    at Object.forEachChild ($MY_PROJECT/node_modules/typescript/lib/typescript.js:12923:24)
    at cb ($MY_PROJECT/node_modules/tslint/lib/rules/objectLiteralShorthandRule.js:81:19)
    at visitNode ($MY_PROJECT/node_modules/typescript/lib/typescript.js:12690:24)
    at Object.forEachChild ($MY_PROJECT/node_modules/typescript/lib/typescript.js:12921:21)
    at cb ($MY_PROJECT/node_modules/tslint/lib/rules/objectLiteralShorthandRule.js:81:19)
    at visitNodes ($MY_PROJECT/node_modules/typescript/lib/typescript.js:12699:30)
    at Object.forEachChild ($MY_PROJECT/node_modules/typescript/lib/typescript.js:12875:24)
    at cb ($MY_PROJECT/node_modules/tslint/lib/rules/objectLiteralShorthandRule.js:81:19)

Expected behavior

No errors.

Needs More Info

Most helpful comment

I had this problem as well, but it turned out to be a mismatch in typescript version. The problem is that the SyntaxKind enum in typescript is not compatible between versions. In my case a 'DefaultClause' was determined to be a property assignment by tsutil because the enum had changed.

All 8 comments

I dropped TS back to 2.6.1 and this went away.

I'm still interested in getting this fixed.
Does the error occur during editing when there are still syntax errors in the code?

To reproduce this, we need a code snippet. To narrow it down to the file that causes the exception, you could edit lib/linter.js. Inside the catch clause of the try-catch in applyRule, you can simply console.log(sourceFile.fileName).

Does the error occur during editing when there are still syntax errors in the code?

Yes, I believe so.

I will try to debug to get you a properly-testable code snippet.


Found the file in question

import { environment } from 'environments/environment';
import { AuthenticationService } from './../../../authentication/services/authentication.service';
import { MarketingInfoActions } from './../../../redux/actions/marketing-info.actions';
import { ValidationService } from './../../services/validation.service';
import { ApplicationService } from './../../../service/application/application.service';
import { LookupService } from './../../../service/lookup/lookup.service';
import { IAccountInfoModel } from './../../models/account-info.model';
import { ILookupItem } from './../../models/lookup-item';
import { Router } from '@angular/router';
import { Component, OnInit, ViewChild } from '@angular/core';
import {
  FormGroup,
  FormBuilder,
  Validators,
  FormControl,
} from '@angular/forms';
import { CustomValidators } from 'ng2-validation/dist';
import { EmailSuggestionComponent } from '../shared/email-suggestion/email-suggestion.component';
import { Campaign } from '../../../shared/utils/campaign';
import { IPAddress } from '../../../shared/utils/ip-address';

// Redux
import { NgRedux } from '@angular-redux/store';
import { AccountInfoActions } from 'app/redux/actions/account-info.actions';
import { UIStateActions } from 'app/redux/actions/ui-state.actions';
import { IAppState } from 'app/redux/store';
import { Observable } from 'rxjs/Observable';
import { IMarketingInfoModel } from 'app/application/models/marketing-info.model';
import { ExistingCustomerMessageComponent } from 'app/authentication/components/existing-customer-message/existing-customer-message.component';

@Component({
  selector: 'x-account',
  templateUrl: './account.component.html',
  styleUrls: ['./account.component.scss'],
  providers: [AccountInfoActions],
})
export class AccountComponent implements OnInit {
  @ViewChild('message') readonly message: ExistingCustomerMessageComponent;
  @ViewChild('suggestedEmail')
  readonly suggestedEmail: EmailSuggestionComponent;

  securityQuestions: ReadonlyArray<ILookupItem> = [];
  accountModel: IAccountInfoModel;
  accountForm: FormGroup;
  marketingModel: IMarketingInfoModel;
  userExistsIn: string;
  validationInProgress: boolean;

  constructor(
    private router: Router,
    private fb: FormBuilder,
    private lookupService: LookupService,
    private applicationService: ApplicationService,
    public validationService: ValidationService,
    public cngCampaign: CNGCampaign,
    public ipAddress: IPAddress,
    private authenticationService: AuthenticationService,
    private navigationActions: UIStateActions,
    // Redux
    private accountInfoActions: AccountInfoActions,
    private marketingInfoActions: MarketingInfoActions,
    private ngRedux: NgRedux<IAppState>
  ) {}

  ngOnInit(): void {
    this.setupForm();
    this.setupFormListeners();
    this.loadData();
    this.setCampaignId();
    this.setIpAddress();
    window.scrollTo(0, 0);
  }

  next(): void {
    if (!this.validationInProgress) {
      this.validationInProgress = true;

      this.validationService.validateForm(this.accountForm);
      if (this.accountForm.valid) {
        this.navigationActions.applicationDataSaving(); // Turn on spinner

        const credentials = this.authenticationService.getCredentials({
          email: this.accountForm.controls.email.value,
          password: this.accountForm.controls.password.value,
        });

        this.authenticationService
          .signUp(credentials)
          .flatMap(result => this.authenticationService.signIn(credentials))
          .catch(err => Observable.throw(err))
          .subscribe(
            result => {
              if (result) {
                this.applicationService
                  .createLoanApplication({
                    accountInfo: {
                      firstName: this.accountForm.controls.firstName.value,
                      lastName: this.accountForm.controls.lastName.value,
                      securityQuestion: this.accountForm.controls
                        .securityQuestion.value,
                      securityAnswer: this.accountForm.controls.securityAnswer
                        .value,
                      email: this.accountForm.controls.email.value,
                      password: this.accountForm.controls.password.value,
                    },
                    marketingInfo: {
                      ipAddress: this.marketingModel.ipAddress,
                      campaignId: this.marketingModel.campaignId,
                    },
                  })
                  .subscribe(response => {
                    this.navigationActions.applicationDataSavingStop(); // Turn off spinner
                    this.accountInfoActions.accountInfoCompleted(
                      this.accountForm.value
                    );
                    this.router.navigate([`/application/personal`]);
                  });
              } else {
              }
            },
            err => {
              this.navigationActions.applicationDataSavingStop(); // Turn off spinner
              if (err.stage === 'SIGNUP') {
                if (err.userExists) {
                  switch (err.source) {
                    case 'PARTIAL':
                    case 'LEGACY':
                      this.userExistsIn = err.source;
                      this.message.showChildModal(
                        'LEGACY'.includes(err.source)
                      );
                      break;
                    default:
                      // this.deleteUser();
                      // can't do this without a JWT
                      break;
                  }
                } else {
                }
              } else if (err.stage === 'SIGNIN') {
                // this.deleteUser();
              } else if (err.stage === 'POSTAPP') {
                // this.deleteUser();
              }
              this.validationInProgress = false;
            }
          );
      } else {
        this.validationInProgress = false;
      }
    }
  }

  goToLogin(): void {
    if (this.userExistsIn === 'LEGACY') {
      window.location.href = `${environment.legacylogin}?email=${
        this.accountForm.get('email').value
      }`;
    } else {
      this.router.navigate(['/login']);
    }
  }

  // private deleteUser():void {
  //   this.authenticationService.deleteUser().subscribe();
  // }

  private setCampaignId(): void {
    this.marketingModel = this.ngRedux.getState().marketingInfo;

    this.marketingModel.campaignId =
      this.marketingModel.campaignId === ''
        ? this.cngCampaign.getCampaignID()
        : this.marketingModel.campaignId;
    this.marketingInfoActions.setCampaignId(this.marketingModel);
  }

  private setIpAddress(): void {
    this.marketingModel = this.ngRedux.getState().marketingInfo;

    if (this.marketingModel.ipAddress === '') {
      this.ipAddress.getIpAddress().subscribe(data => {
        this.marketingModel.ipAddress = data;
        this.marketingInfoActions.setIpAddress(this.marketingModel);
      });
    }
  }

  private loadData(): void {
    this.accountForm.patchValue(this.ngRedux.getState().accountInfo);
  }

  private setupForm(): void {
    const password = new FormControl('', [
      Validators.required,
      Validators.pattern(
        /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d$@$!#%&\(\)\*\+\,\-\.\:\;\<\=\>\?\`\^\[\]{}|~]{8,64}$/
      ),
    ]);

    this.accountForm = this.fb.group({
      firstName: [
        '',
        [
          ,
          Validators.required,
          Validators.minLength(2),
          Validators.pattern('[a-zA-Z ]*'),
        ],
      ],
      lastName: [
        '',
        [
          Validators.required,
          Validators.minLength(2),
          Validators.pattern(`[a-zA-Z ']*`),
        ],
      ],
      email: [
        '',
        [
          Validators.required,
          Validators.pattern(
            /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
          ),
        ],
      ],
      password,
      confirmPassword: [
        '',
        [Validators.required, CustomValidators.equalTo(password)],
      ],
      securityQuestion: ['', [Validators.required]],
      securityAnswer: ['', [Validators.required]],
    });

    this.lookupService
      .getSecurityQuestions()
      .subscribe(data => (this.securityQuestions = data));
  }

  private setupFormListeners(): void {
    this.accountForm.valueChanges
      .filter(x => this.accountForm.valid)
      .debounceTime(300)
      .do(x => this.validationService.validateForm(this.accountForm))
      .subscribe();

    this.accountForm.controls.email.valueChanges
      .filter(value => this.accountForm.controls.email.valid)
      .map(value => value.trim())
      .debounceTime(500)
      .do(value => this.evalUserEnteredEmail(value))
      .subscribe();
  }

  private evalUserEnteredEmail(value: string): void {
    const hasData = this.suggestedEmail.checkEmailDomain(value);
    if (hasData) {
      this.suggestedEmail.hidden = false;
    }
  }
}

I had this problem as well, but it turned out to be a mismatch in typescript version. The problem is that the SyntaxKind enum in typescript is not compatible between versions. In my case a 'DefaultClause' was determined to be a property assignment by tsutil because the enum had changed.

  1. Remove folder node_modules
  2. npm i

These steps worked for me:
1)Clear package.json with the importat packages for example I have delete my package and insert one by one here is my

{
"name": "test-app",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "^6.1.0",
"@angular/cdk": "^6.4.2",
"@angular/common": "^6.1.0",
"@angular/compiler": "^6.1.0",
"@angular/core": "^6.1.0",
"@angular/flex-layout": "^6.0.0-beta.17",
"@angular/forms": "^6.1.0",
"@angular/http": "^6.1.0",
"@angular/material": "^6.4.2",
"@angular/platform-browser": "^6.1.0",
"@angular/platform-browser-dynamic": "^6.1.0",
"@angular/router": "^6.1.0",
"angular2-uuid": "^1.1.1",
"chartist": "^0.11.0",
"core-js": "^2.5.4",
"jquery": "^3.3.1",
"rxjs": "^6.0.0",
"rxjs-compat": "^6.2.2",
"webpack": "^4.16.3",
"zone.js": "~0.8.26"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.7.0",
"@angular/cli": "^6.1.2",
"@angular/compiler-cli": "^6.1.0",
"@angular/language-service": "^6.1.0",
"@types/jasmine": "~2.8.6",
"@types/jasminewd2": "~2.0.3",
"@types/node": "~8.9.4",
"codelyzer": "~4.2.1",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~1.7.1",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.0",
"karma-jasmine": "~1.1.1",
"karma-jasmine-html-reporter": "^0.2.2",
"npm-install-webpack-plugin": "^4.0.5",
"protractor": "~5.3.0",
"ts-node": "~5.0.1",
"tslint": "~5.9.1",
"typescript": "^2.7.2",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "^3.1.5"
}
}
delete package_locked.json
delete node_modules folder
npm install
Then ng build --prod was successful.

Seeing as this is pretty old and looks like it may have been resolved, I'm going to close. Feel free to reopen or tag me if you run into this again.

Was this page helpful?
0 / 5 - 0 ratings