Giter VIP home page Giter VIP logo

typescript-eslint-parser's Introduction

Deprecated: TypeScript ESLint Parser

Important: This repository is no longer maintained and typescript-eslint-parser will not receive any future updates. There is an actively maintained fork of this project available at https://typescript-eslint.io and published on npm as @typescript-eslint/parser.

- typescript-eslint-parser
+ @typescript-eslint/parser

An ESLint custom parser which leverages TypeScript ESTree to allow for ESLint to lint TypeScript source code.

Installation:

npm install --save-dev typescript-eslint-parser

Usage

In your ESLint configuration file, set the parser property:

{
    "parser": "typescript-eslint-parser"
}

There is sometimes an incorrect assumption that the parser itself is what does everything necessary to facilitate the use of ESLint with TypeScript. In actuality, it is the combination of the parser and one or more plugins which allow you to maximize your usage of ESLint with TypeScript.

For example, once this parser successfully produces an AST for the TypeScript source code, it might well contain some information which simply does not exist in a standard JavaScript context, such as the data for a TypeScript-specific construct, like an interface.

The core rules built into ESLint, such as indent have no knowledge of such constructs, so it is impossible to expect them to work out of the box with them.

Instead, you also need to make use of one more plugins which will add or extend rules with TypeScript-specific features.

By far the most common case will be installing the eslint-plugin-typescript plugin, but there are also other relevant options available such a eslint-plugin-tslint.

Configuration

The following additional configuration options are available by specifying them in parserOptions in your ESLint configuration file.

  • jsx - default false. Enable parsing JSX when true. More details can be found here.

    • It's false on *.ts files regardless of this option.
    • It's true on *.tsx files regardless of this option.
    • Otherwise, it respects this option.
  • useJSXTextNode - default true. Please set false if you use this parser on ESLint v4. If this is false, the parser creates the AST of JSX texts as the legacy style.

.eslintrc.json

{
    "parser": "typescript-eslint-parser",
    "parserOptions": {
        "jsx": true,
        "useJSXTextNode": true
    }
}

Supported TypeScript Version

We will always endeavor to support the latest stable version of TypeScript.

The version of TypeScript currently supported by this parser is ~3.2.1. This is reflected in the devDependency requirement within the package.json file, and it is what the tests will be run against. We have an open peerDependency requirement in order to allow for experimentation on newer/beta versions of TypeScript.

If you use a non-supported version of TypeScript, the parser will log a warning to the console.

Please ensure that you are using a supported version before submitting any issues/bug reports.

Integration Tests

We have a very flexible way of running integration tests which connects all of the moving parts of the usage of this parser in the ESLint ecosystem.

We run each test within its own docker container, and so each one has complete autonomy over what dependencies/plugins are installed and what versions are used. This also has the benefit of not bloating the package.json and node_modules of the parser project itself.

If you are going to submit an issue related to the usage of this parser with ESLint, please consider creating a failing integration test which clearly demonstrates the behavior. It's honestly super quick!

You just need to duplicate one of the existing test sub-directories found in tests/integration/, tweak the dependencies and ESLint config to match what you need, and add a new entry to the docker-compose.yml file which matches the format of the existing ones.

Then run:

npm run integration-tests

If you ever need to change what gets installed when the docker images are built by docker-compose, you will first need to kill the existing containers by running:

npm run kill-integration-test-containers

Build Commands

  • npm test - run all linting and tests
  • npm run lint - run all linting
  • npm run integration-tests - run only integration tests

License

TypeScript ESLint Parser is licensed under a permissive BSD 2-clause license.

typescript-eslint-parser's People

Contributors

amilajack avatar armano2 avatar azz avatar dannyfritz avatar despairblue avatar dtaub avatar duailibe avatar dudiharush avatar flying-sheep avatar igorbek avatar ikatyang avatar j-f1 avatar jameshenry avatar jtheoof avatar kaicataldo avatar keplersj avatar mariusschulz avatar michalsnik avatar muhanadra avatar mysticatea avatar not-an-aardvark avatar nzakas avatar pajn avatar platinumazure avatar simenb avatar soda0289 avatar texastoland avatar trusktr avatar uniqueiniquity avatar weirdpattern avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

typescript-eslint-parser's Issues

Automatically create nodes for TypeScript-specific syntax

The original plan was to go through and create custom nodes for TypeScript syntax that would match ESTree format (and Flow format). However, that's going to be a nonstop maintenance issue going forward. Instead, it makes sense to automatically generate the TypeScript nodes for ESLint based on what TypeScript returns. So if TypeScript has a node called StringKeyword (representing the string type), we can create a TSStringKeyword node by:

  1. Creating type as "TSStringKeyword" instead of using the kind field
  2. Copy over any other properties from the TypeScript node onto the ESTree node

For type annotations, we could still get close to Flow by aiming for:

{
    type: "Identifier",
    name: "foo",
    typeAnnotation: {
        type: "TypeAnnotation",
        typeAnnotation: {
            type: "TSStringKeyword"
        }
    }
}

The intermediate TypeAnnotation node is also used by Flow. We would just be using it to hang off a TypeScript-specific node (this will also make it easier for ESLint to deal with).

This would be a first-pass attempt to see how close we can get to something that is usable by ESLint.

Add function type parameters

For code like this:

function a<X>(b:string):X {}

The <X> is missing from the output AST. This should be represented in the typeParameters property of the FunctionDeclaration, like this:

      "typeParameters": {
        "type": "TypeParameterDeclaration",
        "loc": {
          "start": {
            "line": 1,
            "column": 10
          },
          "end": {
            "line": 1,
            "column": 13
          }
        },
        "range": [
          10,
          13
        ],
        "params": [
          {
            "type": "TypeParameter",
            "loc": {
              "start": {
                "line": 1,
                "column": 11
              },
              "end": {
                "line": 1,
                "column": 12
              }
            },
            "range": [
              11,
              12
            ],
            "name": "X",
            "bound": null,
            "variance": null,
            "default": null
          }
        ]
      }

Make TypeScript a peer dependency

Given that some people like riding the edge with TypeScript (e.g. depending on the latest stable or beta version), but others don't always keep up that much (like in some larger projects), it would be nice if, instead, this had TypeScript as a peer dependency instead. Also, the compiler API itself has been pretty consistent across versions, I believe (or it wouldn't be as common to depend on TypeScript this way).

This is typical across the TypeScript tooling, as TSLint, Atom TypeScript, tsify, gulp-typescript, and many others depend on TypeScript in a similar manner. Most of these packages use "typescript": "*" in their package.json.

Another bonus is that this is how most of the tooling could support JSX the moment it was first implemented, but gracefully fall back if the compiler didn't support it.

Student project

Hy everyone

I started with my master degree and we are obligated to write at least two project thesis (and at last the master thesis). I want to focus my project thesis on improving the developer tools for javascript and compile to javascript languages. My first idea was to implement more complex linting rules for javascript, but eslint already supports the most of the rules I came up with. At the other hand I think that type information would allow to implement more complex linting rules.

I have worked for 10 years in various, large, web based, enterprise projects with a focus on javascript for the last 4 years. My last projects have used Typescript, so I'm familiar with the concepts of Typescript (at least up to version 1.7). I have no experience with ESLint as we have used JSHint in our projects.

Personally I'm more interested in flow, but I see that Typescript has the larger community and it's importance will increase in the near future. But at the end I think it's not that important if it is Typescript or Flow that is supported in a first case.

Are you interested in any form of contribution? Are there active contributors? Is someone responsible for the project or is it abandoned? (I don't want to implement something that someone else will implement in the same time, so I think some coordination is required). I'm interested in the benefits you are expecting from adding the type information to ESLint or what your goals are for this project. Have you already some additional rules in mind that require the additional type information or should it be an alternative to TSLint?

Cheers,
Micha

Known Issue with JsxText nodes and whitespace (bug in ts.findNextToken() in tsc)

First off, thanks for creating this! I'm reeeaaally looking forward to being able to use ESLint with TypeScript!

What version of TypeScript are you using?
1.8.10

What version of typescript-eslint-parser are you using?
0.1.3

What code were you trying to parse?

const x = (
  <form>
    <div className={styles.separator}></div>
  </form>
);

What did you expect to happen?
It shouldn't throw an error.

What happened?

eslint --debug C:/path/to/my/file.tsx

  eslint:cli Running on files +0ms
  eslint:ignored-paths Looking for ignore file in C:\Dev+31ms
  eslint:ignored-paths Loaded ignore file C:\Dev\.eslintignore +16ms
  eslint:ignored-paths Adding C:\Dev\.eslintignore +0ms
  eslint:glob-util Creating list of files to process. +0ms
  eslint:cli-engine Processing C:/path/to/my/file.tsx +0ms
  eslint:cli-engine Linting C:/path/to/my/file.tsx +0ms
  eslint:config Constructing config for C:/path/to/my/file.tsx +0ms
  eslint:config Using .eslintrc and package.json files +0ms
  eslint:config Loading C:\Dev\.eslintrc +0ms
  eslint:config-file Loading config file: C:\Dev\.eslintrc +16ms
  eslint:config Using C:\Dev\.eslintrc +203ms
  eslint:config Merging command line environment settings +0ms
  eslint:config-ops Apply environment settings to config +0ms
  eslint:config-ops Creating config for environment browser +0ms
  eslint:config-ops Creating config for environment es6 +0ms
Cannot read property 'range' of undefined
TypeError: Cannot read property 'range' of undefined
    at lastTokenIndex (C:\Dev\node_modules\eslint\lib\token-store.js:41:25)
    at SourceCode.api.getTokenAfter (C:\Dev\node_modules\eslint\lib\token-store.js:114:23)
    at EventEmitter.api.(anonymous function) [as getTokenAfter] (C:\Dev\node_modules\eslint\lib\eslint.js:1033:48)
    at RuleContext.(anonymous function) [as getTokenAfter] (C:\Dev\node_modules\eslint\lib\rule-context.js:155:33)
    at EventEmitter.validateBraceSpacing (C:\Dev\node_modules\eslint-plugin-react\lib\rules\jsx-curly-spacing.js:194:28)
    at emitOne (events.js:82:20)
    at EventEmitter.emit (events.js:169:7)
    at NodeEventGenerator.enterNode (C:\Dev\node_modules\eslint\lib\util\node-event-generator.js:40:22)
    at CodePathAnalyzer.enterNode (C:\Dev\node_modules\eslint\lib\code-path-analysis\code-path-analyzer.js:608:23)
    at CommentEventGenerator.enterNode (C:\Dev\node_modules\eslint\lib\util\comment-event-generator.js:97:23)

Document the tradeoffs for this approach

Awkward issue - but having worked on TSLint lately and wiring it into our toolchain (and we'll start adding angular2 template support soon, + @mgechev ) - I'm curious why you'd want to lint a down-transpiled version of the code. You lose type information of course, plus all the ES7+ features (Esp. decorators) are de-sugared so they're harder to comprehend and analyze.

But I imagine you have a good reason to do this. Too much work to re-implement the checks in TSLint? I imagine adding some utilities to make it much easier to express a certain predicate about an AST subtree...

Development Plan

  • Phase 1: Full ES6 support, stripping out all TypeScript-specific syntax.
  • Phase 2: Add JSX support.
  • Phase 3: Add support for attaching comments.
  • Phase 4: Add support for type annotations (try to mimic what Flow uses and use the type annotations extension to ESTree).
  • Phase 5: Add support for TypeScript-specific syntax (interfaces, etc.). Once again, I'd like to mimic what Flow does as much as possible (with the exception of use "TS" rather than "Flow") where there are commonalities.

Tests fail because of espree not being available

I was simply trying to put together a PR to address #2, but the tests are unable to run because of espree not being available in the project.

All I did was fork the repo and run npm t

npm t

> [email protected] test /Users/james/Sites/typescript-eslint-parser
> node Makefile.js test

No coverage information was collected, exit without writing coverage information
module.js:338
    throw err;
    ^

Error: Cannot find module '../../espree'
    at Function.Module._resolveFilename (module.js:336:15)
    at Function.Module._load (module.js:286:25)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at Object.<anonymous> (/Users/james/Sites/typescript-eslint-parser/tests/lib/attach-comments.js:36:14)
    at Module._compile (module.js:434:26)
    at Module._extensions..js (module.js:452:10)
    at Object.Module._extensions..js (/Users/james/Sites/typescript-eslint-parser/node_modules/istanbul/lib/hook.js:101:13)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)

...ETC...

Type Casting appears to consistently cause errors

I'm using eslint 2.2 and this repo from master. It seems like several rules thow errors due to type casting.

For instance this code:

<any>sinon.stub()

results in this stack trace:

...some removed things.../node_modules/eslint/lib/rules/key-spacing.js:242
            property.key.range[1], property.value.range[0]
                                                 ^

TypeError: Cannot read property 'range' of null
    at getPropertyWhitespace (...some removed things.../node_modules/eslint/lib/rules/key-spacing.js:242:50)
    at verifySpacing (...some removed things.../node_modules/eslint/lib/rules/key-spacing.js:333:22)
    at EventEmitter.Property (...some removed things.../node_modules/eslint/lib/rules/key-spacing.js:373:17)
    at emitOne (events.js:95:20)
    at EventEmitter.emit (events.js:182:7)
    at NodeEventGenerator.enterNode (...some removed things.../node_modules/eslint/lib/util/node-event-generator.js:42:22)
    at CodePathAnalyzer.enterNode (...some removed things.../node_modules/eslint/lib/code-path-analysis/code-path-analyzer.js:591:23)
    at CommentEventGenerator.enterNode (...some removed things.../node_modules/eslint/lib/util/comment-event-generator.js:98:23)
    at Controller.controller.traverse.enter (...some removed things.../node_modules/eslint/lib/eslint.js:839:36)
    at Controller.__execute (...some removed things.../node_modules/eslint/node_modules/estraverse/estraverse.js:397:31)
    at Controller.traverse (...some removed things.../node_modules/eslint/node_modules/estraverse/estraverse.js:495:28)

while removing the casting (and jumping through a few typescript hoops) allows the linter to execute and report normal errors. Can give more info if it'd be helpful. Thanks!

This seems to fail when returning boolean literals

function foo() : boolean {
   return true;
}

causes error:

TypeError: Cannot read property 'match' of undefined
    at EventEmitter.Literal (./node_modules/eslint/lib/rules/no-octal-escape.js:36:37)

The problem is that node.raw is coming in as undefined

typescript-eslint-parser fails on indent rule

Hi,

We are running some tests to evaluate the usage of this parser in order to enable eslint in our typescript projects.
I am using master version and eslint 2.4.0.

I created a small repo which demonstrates our problem:
https://github.com/ranzwix/typescript-eslint-parser-check

It seems that the AST generated by the "code-sample.ts" file and the token-store are not aligned properly, therefore when getting to
"getNodeIndent" function, the code fails to find the appropriate token, and fails on the next line where
the method tries to access the undefined variable properties.
The instructions to run this example are in the repo itself.

Please note that the code passes OK if you remove that rule from the configuration file.

Best regards,
Ran

Identifier used as type definition is recognised as unused

Hi, thanks for your amazing work. I have some feedback but I am very aware this project is still in the very early stages.

When I import an identifier and use it only as a type definition, the parser considers the identifier as unused. It is in fact unused in the JS, but used in the TS. I'm not sure how the parser should handle this?

Versions:

$ npm ls eslint typescript-eslint-parser
/Users/OliverJAsh/Development/samefourchords.com
โ”œโ”€โ”€ [email protected]
โ””โ”€โ”€ [email protected]

ESLint config:

{
    "extends": "eslint:recommended",
    "parser": "typescript-eslint-parser",
    "parserOptions": {
        "ecmaVersion": 6,
        "sourceType": "module",
        "ecmaFeatures": {
            "modules": true
        }
    }
}

Input and output:

$ echo "import { Post } from './models'; let post: Post; post;" > test.js
$ eslint test.js

/Users/OliverJAsh/Development/samefourchords.com/test.js
  1:10  error  'Post' is defined but never used  no-unused-vars

Lint script fails for various reasons

We are making progress, slowly but surely, towards getting this repo ready for active development! This issue is to track changes necessary for the project to be able to lint itself successfully.

There are currently a number of reasons why the lint script is failing, including:

  • Missing semicolons
  • Formatting issues
  • Unused code
  • Missing JSDoc blocks on existing functions

Obviously some of these things are very easy to remedy without having written any of the code, but others are not. The code which is included, but not used, is particularly difficult to reason about.

I will open a PR and look for your feedback on getting this issue resolved.

Then perhaps we can look at getting the lint script to run as a requisite of future PRs?

Error with syntax `import x = require('x')`

Hi, thanks for your amazing work. I have some feedback but I am very aware this project is still in the very early stages.

TypeScript has the syntax import x = require('x') for importing specifically CommonJS modules. (ES6 module syntax is used for ES6 modules.) I have found that when using this syntax, the parser throws because it doesn't recognise the imported identifier. Example below.

Versions:

$ npm ls eslint typescript-eslint-parser
/Users/OliverJAsh/Development/samefourchords.com
โ”œโ”€โ”€ [email protected]
โ””โ”€โ”€ [email protected]

ESLint config:

{
    "extends": "eslint:recommended",
    "parser": "typescript-eslint-parser",
    "parserOptions": {
        "ecmaVersion": 6,
        "sourceType": "module",
        "ecmaFeatures": {
            "modules": true
        }
    }
}

Input and output:

$ echo "import slug = require('slug'); slug;" > test.js
$ eslint test.js
224

/Users/OliverJAsh/Development/samefourchords.com/test.js
  1:32  error  'slug' is not defined  no-undef

โœ– 1 problem (1 error, 0 warnings)

ESLint comment blocks will not work yet

(Note: I am using ESLint via eslint-loader for webpack)
ESLint: 1.9.0
eslint-loader: 1.1.1
typescript-eslint-parser: 0.1.0-alpha-1

I have a codebase which was being transpiled with babel and being linted by eslint using the babel-parser.

After migrating the code to TypeScript and replacing the babel-parser with the typescript-eslint-parser, I have noticed that eslint comment blocks are no longer being respected.

Other than the parser option, no other changes were made to the .eslintrc during the migration.

For example:

/* global d3 */
console.log( d3 )

...used to produce no error or warning, but now shows:
error "d3" is not defined no-undef

The same is true for eslint-disable and eslint-enable comments:

/* eslint-disable no-alert */
alert( 'Hello, World!' )
/* eslint-enable no-alert */

Before introducing typescript-eslint-parser: no feedback from eslint
After introducing typescript-eslint-parser: warning Unexpected alert no-alert

Problem with Interfaces

What version of TypeScript are you using? 1.8.10

What version of typescript-eslint-parser are you using? 0.2.0

What code were you trying to parse?

interface Iwhen {
  (config: Object, thenFunc: Function): any,
  _eventHandlers: Object,
  _attributeHandlers: Array <Object>,
  _propertyListeners: Array <Object>,
  _mutationObserver: MutationObserver
}

.eslintrc

{
  "extends": "airbnb",
  "parser": "typescript-eslint-parser"
}

What did you expect to happen?
From what I could gather from #74 , I should be able to get Linted with no Errors

What happened?

  1:11  error  'Iwhen' is not defined               no-undef
  3:4   error  'config' is not defined              no-undef
  3:20  error  'thenFunc' is not defined            no-undef
  4:3   error  '_eventHandlers' is not defined      no-undef
  5:3   error  '_attributeHandlers' is not defined  no-undef
  6:3   error  '_propertyListeners' is not defined  no-undef
  7:3   error  '_mutationObserver' is not defined   no-undef
  7:22  error  'MutationObserver' is not defined    no-undef

Implement JSX syntax

Phase 2 is to add JSX syntax support into this parser. This would involve:

  1. Converting the TypeScript JSX syntax tree into an ESTree-compatible one.
  2. Convert the TypeScript tokens into Esprima-style tokens.
  3. Making the result pass the JSX tests that are already tests in tests/fixtures/ecma-features/jsx.

@JamesHenry are you interested in taking a stab at this?

Milestone: Decorator Support

This issue it to track progress against supporting decorators within the final AST that the parser produces. We currently remove them during parsing.

We need to ensure that the following are accurately carried over from the original TypeScript AST:

  • Parameter Decorators
    • On instance member
    • On static member
    • In constructor
  • Method Decorators
    • On instance member
    • On static member
  • Accessor Decorators
    • On instance member
    • On static member
  • Property Decorators
    • On instance member
    • On static member
  • Class Decorators

We also need to account for the difference between decorators and decorator factories:

Decorator:
unspecified-11

Decorator Factory:
unspecified-12

At the AST-level, the decorator node has an Identifier TSNode as an expression, whereas the decorator factory has a CallExpression TSNode.

Decorators are not currently covered by the ESTree spec as they are still a fairly early-stage es-proposal, but Angular 2, for example, has adopted them as a core aspect of the framework.

TypeScript adds a decorators array to the node in question, and I propose we do the same.

Resources:
https://www.typescriptlang.org/docs/handbook/decorators.html

TypeScript upgrade breaks the world

It looks like there were some changes in the TypeScript output between 1.6.x and 1.8.x that are causing identifiers to be labeled as keywords in the output. As such, most tests are failing right now.

I'm looking into this.

Rules constructor-super and no-this-before-super are applying for non derived class

  14:5  error  Expected to call 'super()'              constructor-super
  15:9  error  'this' is not allowed before 'super()'  no-this-before-super
export class MockRouteSegment implements RouteSegment {
    urlSegments: any;
    parameters: any;
    outlet: string;
    _type: any;
    _componentFactory: any;
    type: any;
    stringifiedUrlSegments: string;

    constructor(parameters?: { [key: string]: any; }) { // L:14
        this.parameters = parameters; // L:15
    }

    getParam(param: string) {
        return this.parameters[param];
    }
}

MockRouteSegment is not derived class.

Thanks

This is a really awesome project, thanks so much for the great work. Can't wait to see it finished ๐Ÿ˜„

Help from tslint-eslint rules?

Hi there! I don't know a lot about the TS Language Services API but I am cheering for ESLint to support TS very soon! ESLint is pretty fantastic and I think we would all win if there are fewer tools covering a larger area! Besides, eslint configs are far superior to TSLint's.

This project -> https://github.com/buzinas/tslint-eslint-rules uses the reverse methodology. I was just wondering if the core team could have a look at it and get any help from it?

Sorry if this is the wrong place to post this!

TypeError being thrown in no-octal-escape rule

Hi @nzakas,

Thanks so much for getting the ball rolling on this!

I have really enjoyed (and benefitted from) using ESLint with a large Babel-transpiled codebase and it has been flawless. That codebase is now being migrated to TypeScript and I really hope to continue using ESLint, so you may see some issues on here from me.

As a newcomer to world of JS ASTs and linter design, it may take a little while before I am actively contributing, but for now hopefully I can add value by simply reporting what I find.

(Note: I am using ESLint via eslint-loader for webpack)
ESLint: 1.9.0
eslint-loader: 1.1.1
typescript-eslint-parser: 0.1.0-alpha-1

My first issue is that the following error is being thrown a lot within no-octal-escape.js:

Module build failed: TypeError: Cannot read property 'match' of undefined
    at EventEmitter.Literal ({{PROJECT_PATH}}/node_modules/eslint/lib/rules/no-octal-escape.js:26:33)
  • The code in no-octal-escape responsible for the TypeError:
module.exports = function(context) {

    return {

        "Literal": function(node) {
            if (typeof node.value !== "string") {
                return;
            }

            var match = node.raw.match(/^([^\\]|\\[^0-7])*\\([0-3][0-7]{1,2}|[4-7][0-7]|[0-7])/),
                octalDigit;

            if (match) {
                octalDigit = match[2];

                // \0 is actually not considered an octal
                if (match[2] !== "0" || typeof match[3] !== "undefined") {
                    context.report(node, "Don't use octal: '\\{{octalDigit}}'. Use '\\u....' instead.",
                            { octalDigit: octalDigit });
                }
            }
        }

    };

};
  • I tracked down the first "offender" to be this call to angular bootstrap, and specifically the strictDi: true
angular.bootstrap( document, [ 'app' ], {
   strictDi: true
})
  • The node that gets passed through to the "Literal": function(node) { handler (by the typescript-eslint-parser?) has a value of 'true' so it is passing the typeof check, but it does not have a raw property at all.

E.g.

{ type: 'Literal',
  range: [ 1890, 1894 ],
  loc:
   { start: { line: 91, column: 12 },
     end: { line: 91, column: 16 } },
  value: 'true',
  parent:
   { type: 'Property',
     range: [ 1880, 1894 ],
     loc: { start: [Object], end: [Object] },
     key:
      { type: 'Identifier',
        range: [Object],
        loc: [Object],
        name: 'strictDi',
        parent: [Circular] },
     value: [Circular],
     computed: false,
     method: false,
     shorthand: false,
     kind: 'init',
     parent:
      { type: 'ObjectExpression',
        range: [Object],
        loc: [Object],
        properties: [Object],
        parent: [Object] } } }
  • My guess is that node.value should be the boolean value true rather than the string 'true'.

Please let me know if you need any more info!

Phase 3: Attach comments

Phase 3 is to add attaching leading/trailing comments to the AST inside the parser. This would involve:

  1. Retrieving comments for each node.
  2. Converting the TypeScript comments into Esprima-style comments.
  3. Adding the comments into leadingComments and trailingComments arrays on appropriate nodes.
  4. Making the result pass the tests that are already tests in tests/fixtures/attach-comments.

Discussion: Could this be used for Acorn, and then Webpack.

So I've been discussing this at length with @DanielRosenwasser. Because webpack's AST parser is powered by tern/acorn, it would be incredible to have an extension to plugin to allow all sorts of crazy features via webpack. This makes the overall user story for webpack with typescript, and other frameworks far more promising.

I wanted to start the discussion somewhere, and it looks like eslint and webpack have the same common goals when it comes to parsing.

Cannot find module 'acorn-jsx/inject' - dependency missing

(Note: I am using ESLint via eslint-loader for webpack)
ESLint: 1.9.0
eslint-loader: 1.1.1
typescript-eslint-parser: 0.1.0-alpha-1

acornJSX = require("acorn-jsx/inject") is part of the var declaration at the top of parser.js but acorn-jsx is not a dependency of the project.

It doesn't seem like acornJSX is actually used anywhere, would you like a PR with the require statement removed?

no-unused-vars - false positive for class props defined via public/private keywords in constructor

(Note: I am using ESLint via eslint-loader for webpack)
ESLint: 1.9.0
eslint-loader: 1.1.1
typescript-eslint-parser: 0.1.0-alpha-1

Take this valid ES2015 code:

class MyClass {
  constructor( foo ) {
    this.foo = foo
  }
  bar() {
    return this.foo
  }
}

In TypeScript, we can make use of the public or private keywords to skip having to manually assign the constructor param to the instance, so it becomes:

class MyClass {
  constructor( public foo ) {}
  bar() {
    return this.foo
  }
}

Currently the second version will erroneously produce a no-unused-vars error for foo because, as far as eslint is concerned, it is not used in the constructor

Parser cannot parse inside decoration syntax

import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {AppComponent} from './app.component';

@NgModule({
  imports: [
    BrowserModule
  ],
  declarations: [
    AppComponent
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}
  1:9  warning  'NgModule' is defined but never used       no-unused-vars
  2:9  warning  'BrowserModule' is defined but never used  no-unused-vars
  3:9  warning  'AppComponent' is defined but never used   no-unused-vars

I'm using in [email protected] and [email protected]. typescript-eslint-parser cannot perse the decorators syntax and inside the @NgModule() argument object. It was displayed no-unused-vars in spite of actually it's using inside argument.

Type annotations being caught by space-infix-ops rule

(Note: I am using ESLint via eslint-loader for webpack)
ESLint: 1.9.0
eslint-loader: 1.1.1
typescript-eslint-parser: 0.1.0-alpha-1

The following code shows how a variable, foo, can be explicitly annotated with type string
let foo: string = 'bar'

Currently this causes the space-infix-ops rule to error (if enabled).

Re-writing to:
let foo : string = 'bar'

...does fix the eslint error, and is technically not a TypeScript error (example).

However, I would argue that the vast majority of people write their annotations using the first form, and that is certainly what comes through in all the documentation and examples from Microsoft.

It would therefore not be the intention of users who have enabled the space-infix-ops rule to receive an error for let foo: string = 'bar'

ParameterDecorators throwing parse errors

Environment:

eslint: 2.2.0
typescript-eslint-parser: master (npm publish is needed to update the project)


Issue:

Currently when parsing a file which contains a ParameterDecorator eslint will return Parsing error: Unexpected token. This is not the case for ClassDecorators.


Background to my use case:

ParameterDecorators are super useful in an Angular world for dependency injection annotations.

Angular has long since used function parameters as a way to supply dependencies to services, controllers, components etc.

The name of the parameter is important, as the injector uses it to look up the value of the dependency that was registered against it, therefore to ensure that it survives minification you can add a static $inject array to the function/class and specify the names of the dependencies as strings.

E.g. pre-TypeScript:

function MyService( MyDependency ) {
  console.log(MyDependency)
}
MyService.$inject = ['MyDependency']

Using a ParameterDecorator with TypeScript, we can built that static $inject array dynamically based on the value passed in to the decorator:

function Inject( injectableName: string ): ParameterDecorator {
    return function parameterDecorator( target: Object, propertyKey: string, parameterIndex: number ) {
        // if propertyKey is set we are injecting into static method not to constructor
        const injectionTarget: any = propertyKey ? target[ propertyKey ] : target
        injectionTarget.$inject = injectionTarget.$inject || []
        injectionTarget.$inject[ parameterIndex ] = injectableName
    }
}

class MyService {
    constructor(@Inject('MyDependency') MyDependency) {
        console.log(MyDependency)
    }
}
console.log(MyClass.$inject) // ['MyDependency']

Angular 2 will also make heavy use of ParameterDecorators for its dependency injection out of the box.

IDE config

Add IDE config with settings corresponding to eslint code style

npm seems to give me either an old version or a broken version

Forgive me if this is user error or expected behavior; I am new to npm.

I originally had "typescript-eslint-parser": "0.1.0-alpha-1" in package.json, but, examining the contents of node_modules/typescript-eslint-parser/parser.js showed that the version looked old and did not include the recent about JSX syntax, which typescript-eslint-parser-0.1.0-alpha.1.zip from github did include. Eventually I realised the difference is the . instead of - after alpha. Confusing.

Changing to "typescript-eslint-parser": "0.1.0-alpha.1" in package.json, seems to make it install a newer version, however i get this stack trace when invoking eslint, with typescript-eslint-parser configured as the parser:

TypeError: Cannot read property 'loc' of undefined
    at getNodeIndent (node_modules/eslint/lib/rules/indent.js:219:54)
    at checkNodeIndent (node_modules/eslint/lib/rules/indent.js:248:30)
    at node_modules/eslint/lib/rules/indent.js:272:17
    at Array.forEach (native)
    at checkNodesIndent (node_modules/eslint/lib/rules/indent.js:266:19)
    at EventEmitter.Program (node_modules/eslint/lib/rules/indent.js:706:21)
    at emitOne (events.js:101:20)
    at EventEmitter.emit (events.js:188:7)
    at NodeEventGenerator.enterNode (node_modules/eslint/lib/util/node-event-generator.js:40:22)
    at CodePathAnalyzer.enterNode (node_modules/eslint/lib/code-path-analysis/code-path-analyzer.js:607:23)

convert() logging node.kind to console

The default on convert's switch on node.kind logs it to the console. I understand that may be useful while hacking on the parser, but it's kinda distracting when trying to actually use the parser. :-)

Maybe this could be hidden behind a debug variable or configuration option?

Discussion: Extending core ESLint rules to "just work" with TS-specific nodes

In agreement with @nzakas, I wanted to start a discussion here which summarises the findings so far on which core ESLint rules currently have issues with TypeScript-specific concepts, such as interfaces and decorators.

We do have a few options open to us with regards to making this all work (and the eslint-plugin-typescript plugin will still have its place regardless), but we are in agreement that it would be awesome if we did not have to duplicate any existing rules where all we are trying to do is match the same functionality as on standard JS nodes.

I have been running all of the core rules over a large TypeScript codebase (definitely not an exhaustive use of TypeScript features in there, but it's a great start) and noted the following, some of which is fairly subjective:


Rule: camelcase

We have the ability to control whether or not camelcase will apply to object properties, e.g.

"camelcase": ["error", { "properties": "never" }]

Opinion: We should be able to do this for TypeScript interfaces properties too


Rule: keyword-spacing

We can enforce spaces before and after keywords like so:

"keyword-spacing": ["error", { "before": true, "after": true }]

Opinion: We should be able to make type "casting" exempt from this in some way

E.g. I had this example:

<models.ICreativeTemplate>this.currentCreative.template

...where I would not want to put a space between the > and this keyword, but the rule naturally wants me to.


Rule: no-undef

With TypeScript, we are supporting class properties and interfaces. These are both causing false negatives with no-undef:

class A {
  foo = true
}

/* ESLint:
error, 'foo' is not defined
interface MyInterface {
  bar: string,
  baz: number
}

/* ESLint:
error, 'MyInterface' is not defined
error, 'bar' is not defined
error, 'baz' is not defined

It is very likely there are more TypeScript features that will cause the same, but currently those two are so noisy in my codebase that it is not worth investigating further.

This was also reported here: #75


Rule: no-used-vars

There are a couple of things causing false negatives with no-unused-vars:

(1) Class properties created via the constructor, and then later used in a method

class SomeClass {
    constructor(
        private foo: string
    ) {}
    someMethod() {
        return this.foo
    }
}

/* ESLint:
error, 'foo' is defined but never used

(2) Decorators

import { Injectable } from 'foo-framework'

@Injectable()
class Service {}

/* ESLint:
error, 'Injectable' is defined but never used

This was also reported here: #55


Rule: no-useless-constructor

Using the same class property assignment within a constructor example from above, we will also get a false negative on no-useless-constructor

class SomeClass {
    constructor(
        private foo: string
    ) {}
    someMethod() {
        return this.foo
    }
}

/* ESLint:
error, Useless constructor

Rule: space-infix-ops

This rule is basically unusable, given the type annotation syntax :


Rule: semi

It was pointed out here #61 (comment) that TypeScript-only statements will currently not be detectable as needing a semi-colon.

E.g.

"semi": ["error", "always"]
type Result<T> = Success<T> | Failure

/* ESLint:
(No error reported, but should point out missing semi-colon)

i++ should be parsed as UpdateExpression/++ rather than UnaryExpression/PlusPlusToken

I ran into this while debugging why this got flagged with eslint:

let i = 0;
function f() {
  i++;
}
f();

The error is 'i' is never reassigned. Use 'const' instead.

The esprima parse for the i++ looks like this:

          {
            "expression": {
              "argument": {
                "name": "i",
                "type": "Identifier"
              },
              "operator": "++",
              "prefix": false,
              "type": "UpdateExpression"
            }

whereas the typescript-eslint-parser equivalent is:

            "expression": {
              "argument": {
                "name": "i",
                "type": "Identifier"
              },
              "operator": "PlusPlusToken",
              "prefix": false,
              "type": "UnaryExpression"
            }

__dirname should not cause error when using node env

Hi, thanks for your amazing work. I have some feedback but I am very aware this project is still in the very early stages.

Versions:

$ npm ls eslint typescript-eslint-parser
/Users/OliverJAsh/Development/samefourchords.com
โ”œโ”€โ”€ [email protected]
โ””โ”€โ”€ [email protected]

ESLint config:

{
    "extends": "eslint:recommended",
    "parser": "typescript-eslint-parser",
    "env": {
        "node": true
    }
}

Input and output:

$ echo "console.log(__dirname)" > test.js
$ eslint test.js

/Users/OliverJAsh/Development/samefourchords.com/test.js
  1:1   error  Unexpected console statement  no-console
  1:13  error  '___dirname' is not defined   no-undef

Since I set the node env to true, I do not expect __dirname to cause an error.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.