Coder Social home page Coder Social logo

typescript-eslint / typescript-eslint Goto Github PK

View Code? Open in Web Editor NEW
14.6K 89.0 2.6K 58.53 MB

:sparkles: Monorepo for all the tooling which enables ESLint to support TypeScript

Home Page: https://typescript-eslint.io

License: Other

JavaScript 2.64% TypeScript 89.85% Vue 0.04% Shell 0.01% CSS 0.50% MDX 6.96%
typescript eslint eslint-plugin tslint eslintplugin plugin

typescript-eslint's Introduction

typescript-eslint

Monorepo for the tooling that enables ESLint and Prettier to support TypeScript

CI Financial Contributors on Open Collective NPM Downloads Codecov

πŸ‘‡

See typescript-eslint.io for documentation on the latest released version.

See main--typescript-eslint.netlify.app for documentation on the latest canary release.

πŸ‘†

Code Contributors

This project exists thanks to the awesome people who contribute code and documentation:

Gallery of all contributors' profile photos

πŸ™ An extra special thanks goes out to the wonderful people listed in CONTRIBUTORS.md

Financial Contributors

In addition to submitting code and documentation updates, you can help us sustain our community by becoming a financial contributor [Click here to contribute - every little bit helps!]

Deploys by Netlify

License

typescript-eslint inherits from the original TypeScript ESLint Parser license, as the majority of the work began there. It is licensed under a permissive BSD 2-clause license.

typescript-eslint's People

Contributors

a-tarasyuk avatar armano2 avatar auvred avatar bmish avatar bradzacher avatar dependabot[bot] avatar fisker avatar g-rath avatar greenkeeper[bot] avatar j-f1 avatar jameshenry avatar josh-cena avatar joshuakgoldberg avatar kirkwaiblinger avatar lonyele avatar michaeldeboey avatar nzakas avatar phaux avatar rafaelss95 avatar rebeccastevens avatar renovate[bot] avatar retsam avatar scottohara avatar soda0289 avatar sosukesuzuki avatar typescript-eslint[bot] avatar uniqueiniquity avatar weirdpattern avatar yeonjuan avatar zamiell 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  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

typescript-eslint's Issues

no-useless-constructor: class declaration with constructor throws exception

This issue was initially reported here: eslint/typescript-eslint-parser#485


What version of TypeScript are you using?
2.9.1

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

What code were you trying to parse?

// foo.ts
declare class Foo {
  constructor();
}

or

// foo.d.ts
class Foo {
  constructor();
}

What did you expect to happen?
No exception.

What happened?

TypeError: Cannot read property 'body' of null
    at checkForConstructor (/Users/OliverJAsh/Development/unsplash-web/node_modules/eslint/lib/rules/no-useless-constructor.js:167:41)
    at listeners.(anonymous function).forEach.listener (/Users/OliverJAsh/Development/unsplash-web/node_modules/eslint/lib/util/safe-emitter.js:47:58)
    at Array.forEach (native)
    at Object.emit (/Users/OliverJAsh/Development/unsplash-web/node_modules/eslint/lib/util/safe-emitter.js:47:38)
    at NodeEventGenerator.applySelector (/Users/OliverJAsh/Development/unsplash-web/node_modules/eslint/lib/util/node-event-generator.js:251:26)
    at NodeEventGenerator.applySelectors (/Users/OliverJAsh/Development/unsplash-web/node_modules/eslint/lib/util/node-event-generator.js:280:22)
    at NodeEventGenerator.enterNode (/Users/OliverJAsh/Development/unsplash-web/node_modules/eslint/lib/util/node-event-generator.js:294:14)
    at CodePathAnalyzer.enterNode (/Users/OliverJAsh/Development/unsplash-web/node_modules/eslint/lib/code-path-analysis/code-path-analyzer.js:608:23)
    at Traverser.enter [as _enter] (/Users/OliverJAsh/Development/unsplash-web/node_modules/eslint/lib/linter.js:865:28)
    at Traverser._traverse (/Users/OliverJAsh/Development/unsplash-web/node_modules/eslint/lib/util/traverser.js:132:14)

Possibly related to eslint/typescript-eslint-parser#384?

[no-magic-number] fails on numeric literal types

Note: this issue was originally filed here eslint/typescript-eslint-parser#588.

The original issue (now archived) was marked as closed, and suggested as being fixed by eslint/typescript-eslint-parser#596, however it does still appear to be an issue when using the latest 1.0.0 versions of the parser & plugin from the @typescirpt-eslint monorepo (unless I'm holding it wrong).

What code were you trying to parse?

{
	"parser": "@typescript-eslint/parser",
	"plugins": ["@typescript-eslint"],
	"rules": {
		"no-magic-numbers": "error"
	}
}
type Amount = 10 | -10;

const movement: Amount = 10

What did you expect to happen?
No errors

What actually happened?

  1:15  error  No magic number: 10   no-magic-numbers
  1:20  error  No magic number: -10  no-magic-numbers

The magic numbers that the rule is complaining about are the allowed values of the Typescript numeric literal type type Amount = 10 | -10.

I'm not aware of any way to define a numeric literal type that doesn't violate the magic numbers rule?

Versions

package version
@typescript-eslint/parser 1.0.0
TypeScript 3.2.1
ESLint 5.11.1
node 11.5.0
npm 6.5.0

Converting rules to be in TypeScript

I was wondering people's thoughts of switching this repository over to using TypeScript. Personally I find it much easier to code using TypeScript, especially on an unfamiliar codebase. One of the nice things about developing rules on TSLint is that you can write rules in either TypeScript or JavaScript.

I was thus curious had we considered allowing people to write rules with TypeScript?

TypeError: context.report() called with a messageId, but no messages were present in the rule metadata

Repro

{
  "extends": ["plugin:@typescript-eslint/recommended"], // actually error happens when i add this line
  "plugins": ["@typescript-eslint/eslint-plugin"],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": 2018,
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true
    }
  },
  "settings": {
    "import/resolver": {
      "node": {
        "extensions": [".js", ".jsx", ".ts", ".tsx", ".json"]
      }
    }
  }
}
any file

Expected Result

Actual Result

Additional Info

[Error - 11:09:59 PM] ESLint stack trace:
[Error - 11:09:59 PM] TypeError: context.report() called with a messageId, but no messages were present in the rule metadata.
    at args (/Users/vladimir/projects/tatt-battle/client/node_modules/eslint/lib/util/report-translator.js:252:23)
    at Object.report (/Users/vladimir/projects/tatt-battle/client/node_modules/eslint/lib/linter.js:720:41)
    at report (/Users/vladimir/projects/tatt-battle/client/node_modules/eslint/lib/rules/indent.js:712:21)
    at Program:exit.sourceCode.lines.forEach (/Users/vladimir/projects/tatt-battle/client/node_modules/eslint/lib/rules/indent.js:1599:25)
    at Array.forEach (<anonymous>)
    at Program:exit (/Users/vladimir/projects/tatt-battle/client/node_modules/eslint/lib/rules/indent.js:1560:38)
    at listeners.(anonymous function).forEach.listener (/Users/vladimir/projects/tatt-battle/client/node_modules/eslint/lib/util/safe-emitter.js:45:58)
    at Array.forEach (<anonymous>)
    at Object.emit (/Users/vladimir/projects/tatt-battle/client/node_modules/eslint/lib/util/safe-emitter.js:45:38)
    at NodeEventGenerator.applySelector (/Users/vladimir/projects/tatt-battle/client/node_modules/eslint/lib/util/node-event-generator.js:251:26)

Versions

package version
@typescript-eslint/eslint-plugin ^0.2.1
@typescript-eslint/parser ^0.2.1
typescript ^3.2.4

[explicit-function-return-type] only apply to exported functions

I'd like to propose a change to an existing rule.

Description

It can be unnecessarily verbose to type every single functions return type, but I'd love to enforce typing of functions exported from a file. I find that then the type errors are closer to the actual error, rather than having bubbled up multiple functions, while still being less onerous to do. Thoughts?

Unused Variables When Used As Typings

This issue was initially reported here: eslint/typescript-eslint-parser#599


I'm still new to TypeScript so apologizes if I misunderstood this issue.

What version of TypeScript are you using?
3.2.2

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

What code were you trying to parse?

import * as fastify from 'fastify'
import { Server, IncomingMessage, ServerResponse } from 'http'

// Create a http server. We pass the relevant typings for our http version used.
// By passing types we get correctly typed access to the underlying http objects in routes.
// If using http2 we'd pass <http2.Http2Server, http2.Http2ServerRequest, http2.Http2ServerResponse>
const server: fastify.FastifyInstance<Server, IncomingMessage, ServerResponse> = fastify({})

const opts: fastify.RouteShorthandOptions = {
  schema: {
    response: {
      200: {
        type: 'object',
        properties: {
          pong: {
            type: 'string'
          }
        }
      }
    }
  }
}

server.get('/ping', opts, (request, reply) => {
  console.log(reply.res) // this is the http.ServerResponse with correct typings!
  reply.code(200).send({ pong: 'it worked!' })
})

From: https://github.com/fastify/fastify/blob/master/docs/TypeScript.md#example

What did you expect to happen?
No errors relating unused variables.

What happened?
It complains that Server, IncomingMessage, ServerResponse are all unused but technically they are used when defining the server variable.

Documentation: Getting Started Guide and User Journeys

We should document the potential journeys to guide users through setting up our various packages. I see three main paths:

  1. I want to start linting my TypeScript project with ESLint

  2. I am already linting my TypeScript project with TSLint and I want to switch to ESLint

  3. I am converting my project from JavaScript to TypeScript and I want to keep using ESLint

I think breaking down the docs like this will make everything much more approachable.

[strict] False positive for modules that don't export

Repro

If I have a file that has no exports and I have sourceType: module, it still reports a failure on the strict rule. I import the file for its global side effects.

root: true
env:
  browser: true
  es6: true
  commonjs: true

extends:
  - eslint:all
  - plugin:react/all
  - plugin:eslint-plugin-jsx-a11y/recommended
  - plugin:fp/recommended
  - plugin:import/errors

parserOptions:
  ecmaVersion: 2018
  ecmaFeatures:
    jsx: true
  sourceType: module

plugins:
  - better
  - fp
  - eslint-plugin-jsx-a11y
  - import
  - react

overrides:
  - files: ['**/*.ts', '**/*.tsx']
    parser: typescript-eslint-parser
    plugins: [typescript]
    rules:
      no-undef: off
      typescript/no-unused-vars: error

settings:
  import/resolver:
    node:
      moduleDirectory:
        - app/javascript
        - spec/javascript
        - vendor/assets/javascripts
        - node_modules
      extensions: [.js, .jsx, .ts, .tsx]
    babel-module:
      - root:
        - './app'
  import/extensions: [js, jsx]
window.whatevs = {
  myFunc() {
    console.log('yep');
  }
};

Expected Result

No linter error should be reported.

Actual Result

2:9  error  Use the function form of 'use strict'                      strict

Additional Info

This works as expected if I change the file to be js, so seems to be something related to changing it to ts.

Versions

package version
eslint-plugin-typescript 0.13.0
typescript-eslint-parser 17.0.1
typescript 2.9.3

import/export: false positives

This issue was initially reported here: eslint/typescript-eslint-parser#444


What version of TypeScript are you using?
2.6.1

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

What code were you trying to parse?

// unexected error: Multiple exports of name 'Foo'. (import/export)
export const Foo = 1;
// unexected error: Multiple exports of name 'Foo'. (import/export)
export type Foo = 1;

The import/export rule is defined here: https://github.com/benmosher/eslint-plugin-import/blob/219a8d2e5af230f73b4754f725916843645889ff/docs/rules/export.md

Is this an issue to log here or with the eslint-plugin-import project?

We've decided to disable this ESLint rule as TypeScript also provides similar functionality anyway, but logging this just for others/reference.

For context, this pattern is common when using unionize:

import { unionize, ofType } from 'unionize'

export const Action = unionize({
  ADD_TODO:                ofType<{ id: string; text: string }>(),
  SET_VISIBILITY_FILTER:   ofType<'SHOW_ALL' | 'SHOW_ACTIVE' | 'SHOW_COMPLETED'>(),
  TOGGLE_TODO:             ofType<{ id: string }>(),
});

export type Action = typeof Action._Union;

Rule parity with TSLint core

Feature request: support looking up tsconfig.json relative to linted file

Currently, the eslint-plugin-tslint throws if any of:

      /**
       * The user needs to have configured "project" in their parserOptions
       * for @typescript-eslint/parser
       */
      if (!parserServices || !parserServices.program) {
        throw new Error(
          `You must provide a value for the "parserOptions.project" property for @typescript-eslint/parser`
        );
      }

or lintFile are missing. If lintFile is missing it'll just lint nothing instead of throwing, unless there are inline configs.


parserOptions.project is completely undocumented in @typescript-eslint/parser, and at any rate that would need to be autodetectable for this use case to work. Currently, services are just silently not generated if it's missing:

  const shouldProvideParserServices =
    shouldGenerateServices && extra.projects && extra.projects.length > 0;

This is despite there being a getASTAndDefaultProject, which looks like it could do the right thing. It's just unreachable code unless you already gave a project to begin with.

On further reading, it looks like the tsconfig.json can be relative, but it's by default calculated relative to process.cwd() and not to the current eslintrc being processed, or an ancestor lookup relative to the current file. The option to change that (tsconfigRootDir) is also undocumented and still can't do what I want.


Secondly, it should be possible to make the tslint.json also be relative to either the current tsconfig.json, the current eslintrc, or to also do a ancestor lookup from the current file.


I think that for most people's use cases the process.cwd() or path.resolve(__dirname, "tslint.json") approach could work, but in my use case I'm trying to make a single shareable eslint config for a monorepo and simply reuse it with "eslintConfig": { "extends": ["@scope/eslint-config"] }. This works for me for everything except these use cases. Note that path.resolve(__dirname, "tslint.json") would still be wrong if a specific project has a different tslint.json than the one the shared eslint-config has.

Even if I leave it to run per project, I still have some specific folders that have a different tsconfig.json nested inside an outer tsconfig.json that belongs to the same project. e.g. a service worker would have worker instead of dom in its lib config. I can still probably deal with this through refactoring, but it sounds like something that could/should be supported; or at least vscode can support it.

[explicit-function-return-type] Add fixer

Once we have access to type information, we should consider adding a fixer for explicit-function-return-type.
As long as the parser provides the information we need, that is!!

Would be really convenient for simple types + named/interface types!

function str() { // fix to :string
  return 'string';
}
function bool() { // fix to :boolean
  return true;
}
function num() { // fix to :number
  return 1.0;
}
function symb() { // fix to :symbol
  return Symbol('yas');
}

enum FooEnum { bar }
function enumm() { // fix to :FooEnum
  return FooEnum.bar
}

type FooObjType = { bar: number };
function namedType() { // fix to :FooObjType
  const x : FooObjType = { bar: 1 };
  return x;
}O

interface IFoo = { bar: number };
function namedType() { // fix to :IFoo
  const x : IFoo = { bar: 1 };
  return x;
}

Not sure how useful it would be for unnamed object types, but could be configurable if people don't find it useful

// do we fix to :{ bar: number } ???
function namedType() {
  const x = { bar: 1 };
  return x;
}

[no-explicit-any] Adding switches for supported options

I'd like to propose a change to an existing rule.

How about adding extra options to the no-explicit-any rule?
I'm thinking switches for the multiple cases that are currently supported, but my main concern is with the generic array declaration when the array is used as a rest parameter.

I'm not proposing any specifics and not doing any work on it just yet as I want to hear from the community before I (or who ever wants to take it) start working on it...

So, thoughts?

Benchmarking against TSLint

First up, thanks so much for all of the work on this. I've long watched (and used) this project wondering if the community would eventually converge on TSLint or ESLint for checking TypeScript code and am really excited to see the recent progress on this project.

Once this project hits 1.0 it would be interesting to benchmark it against TSLint on some largish codebases. This would not only help people in deciding which to use (although speed is only a minor concern IMO, number and features of rules and community adoption would be more important to me) but it could also potentially help find bottlenecks in different rules.

Object spread in JSX causes lint errors to not show

This issue was initially reported here: eslint/typescript-eslint-parser#512


What version of TypeScript are you using?
3.0.3

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

What code were you trying to parse?

import React from 'react';
import styled from 'styled-components';
import CardContent from '@material-ui/core/CardContent';
import TextField from '../../../components/TextField';
import Title from '../../../components/Title';
import Button from '../../../components/Button';

const SendTransaction = props => (
  <Content>
    <Title>Send Payment</Title>
    <Section>
      <TextField
        name="receiveraddress"
        label="ReceiverΒ΄s Address"
        value={props.receiveraddress}
        type="text"
        onChange={props.onChange}
      />
    </Section>
    <Section>
      <TextField
        name="receivername"
        label="ReceiverΒ΄s Name (Optional)"
        value={props.receivername}
        type="text"
        onChange={props.onChange}
      />
    </Section>
    <Section>
      <TextField name="amount" label="Amount to Send" value={props.amount} type="text" {...props} />
    </Section>
    <Section>
      <Button onClick={props.makeTransaction} text="Make Payment" />
    </Section>
  </Content>
);

const Content = styled(CardContent)``;

const Section = styled.div`
  padding: 10px;
`;

export default SendTransaction;

What did you expect to happen?
I should get errors for react/prop-types.

What happened?
No errors.

.eslintrc.json
Tried 2:

{
  "parser": "typescript-eslint-parser",
  "parserOptions": {
    "ecmaVersion": 2018,
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true
    }
  },
  "plugins": ["react"],
  "rules": {
    "react/prop-types": [1, { "ignore": ["children"] }]
  }
}

and:

{
  "env": {
    "es6": true
  },
  "parser": "typescript-eslint-parser",
  "parserOptions": {
    "ecmaVersion": 2018,
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true,
      "spread": true,
      "experimentalObjectRestSpread": true
    }
  },
  "ecmaFeatures": {
    "spread": true,
    "experimentalObjectRestSpread": true
  },
  "plugins": ["react"],
  "rules": {
    "react/prop-types": [1, { "ignore": ["children"] }]
  }
}

Reason
It is due to the {...props}. As soon as I remove that, I get the react/prop-types errors.

[typescript/indent] Crash

Repro

{
  "rules": {
    "indent": "off",
    "typescript/indent": ["error", 4, { "SwitchCase": 1 }]
  }
}

I don't know which code throw the problem.
The repo is available here:
https://github.com/quadre-code/quadre-git/tree/9a7f6b7226473e67f433217d25b80a6bf8d4a094

Expected Result
Not crash

Actual Result

TypeError: context.report() called with a messageId, but no messages were present in the rule metadata.
    at args (<...>\quadre-git\node_modules\eslint\lib\util\report-translator.js:252:23)
    at Object.report (<...>\quadre-git\node_modules\eslint\lib\linter.js:720:41)
    at report (<...>\quadre-git\node_modules\eslint\lib\rules\indent.js:712:21)
    at Program:exit.sourceCode.lines.forEach (<...>\quadre-git\node_modules\eslint\lib\rules\indent.js:1599:25)
    at Array.forEach (<anonymous>)
    at Program:exit (<...>\quadre-git\node_modules\eslint\lib\rules\indent.js:1560:38)
    at listeners.(anonymous function).forEach.listener (<...>\quadre-git\node_modules\eslint\lib\util\safe-emitter.js:45:58)
    at Array.forEach (<anonymous>)
    at Object.emit (<...>\quadre-git\node_modules\eslint\lib\util\safe-emitter.js:45:38)
    at NodeEventGenerator.applySelector (<...>\quadre-git\node_modules\eslint\lib\util\node-event-generator.js:251:26)

Additional Info
Log taken with ./node_modules/.bin/eslint --ext .ts ./src --debug &> eslint-log.txt
eslint-log.txt

In my editor I also see this log, I don't know if it is related.

Error thrown in executeOnText: TypeError: Cannot read property 'range' of undefined
    at SourceCode.getFirstTokenBetween (<...>\quadre-git\node_modules\eslint\lib\token-store\index.js:340:18)
    at Object.BinaryExpression, LogicalExpression [as listener] (<...>\quadre-git\node_modules\eslint\lib\rules\indent.js:1068:45)
    at Program:exit.listenerCallQueue.filter.forEach.nodeInfo (<...>\quadre-git\node_modules\eslint\lib\rules\indent.js:1543:55)
    at Array.forEach (<anonymous>)
    at Program:exit (<...>\quadre-git\node_modules\eslint\lib\rules\indent.js:1543:26)
    at listeners.(anonymous function).forEach.listener (<...>\quadre-git\node_modules\eslint\lib\util\safe-emitter.js:45:58)
    at Array.forEach (<anonymous>)
    at Object.emit (<...>\quadre-git\node_modules\eslint\lib\util\safe-emitter.js:45:38)
    at NodeEventGenerator.applySelector (<...>\quadre-git\node_modules\eslint\lib\util\node-event-generator.js:251:26)
    at NodeEventGenerator.applySelectors (<...>\quadre-git\node_modules\eslint\lib\util\node-event-generator.js:280:22)

Versions

package version
eslint-plugin-typescript 1.0.0-rc.3
typescript-eslint-parser eslint-plugin-typescript/parser
typescript 3.1.6

[explicit-function-return-type] Allow implicit void functions

It would be nice if this rule had an option to ignore errors for void functions not explicitly marked as such.

Currently:

// Invalid: Missing return type on function
function hello() {
	console.log('Hello');
}

After:

{
	"rules": {
		"typescript/explicit-function-return-type": [
			"error",
			{
				"allowVoid": true
			}
		]
	}
}
// Valid
function hello() {
	console.log('Hello');
}

// Also valid
function something(props, text): void {
	props.text = text;
	return;
}

no-undef: false flag on `typeof argument` types

This issue was initially reported here: eslint/typescript-eslint-parser#557


What version of TypeScript are you using?
3.1.6

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

What code were you trying to parse?

interface IteratorCallback<Subject, Key, Value> {
	(this: Subject, value: Value, key: Key, subject: Subject): void | false
}
function eachr<Value>(subject: Array<Value>, callback: IteratorCallback<typeof subject, number, Value>): typeof subject;
function eachr<Key, Value>(subject: Map<Key, Value>, callback: IteratorCallback<typeof subject, Key, Value>): typeof subject;
function eachr<Object extends object, Key extends keyof Object>(subject: Object, callback: IteratorCallback<Object, Key, Object[Key]>): Object;
function eachr<Object extends object, Key, Value> (subject: Object | Array<Value> | Map<Key, Value>, callback: IteratorCallback<typeof subject, Key, Value>): typeof subject {
	return subject
}

export default eachr

What did you expect to happen?
Just get back:

  7:102  warning  'callback' is defined but never used  no-unused-vars

What happened?

Got back no-undef errors:

  4:80   error    'subject' is not defined              no-undef
  4:113  error    'subject' is not defined              no-undef
  5:88   error    'subject' is not defined              no-undef
  5:118  error    'subject' is not defined              no-undef
  7:102  warning  'callback' is defined but never used  no-unused-vars

Here is the .eslintrc:

{ extends: [ 'eslint:recommended' ],
  plugins: [ 'typescript', 'babel' ],
  parserOptions:
   { ecmaFeatures: { jsx: false },
     sourceType: 'module',
     ecmaVersion: 5 },
  env:
   { es6: false,
     node: true,
     browser: true,
     commonjs: true,
     'shared-node-browser': true },
  rules:
   { 'no-cond-assign': [ 2, 'always' ],
     'no-console': 1,
     'no-constant-condition': 1,
     'no-control-regex': 2,
     'no-debugger': 1,
     'no-dupe-args': 2,
     'no-dupe-keys': 2,
     'no-duplicate-case': 2,
     'no-empty': 0,
     'no-empty-character-class': 2,
     'no-ex-assign': 2,
     'no-extra-boolean-cast': 2,
     'no-extra-parens': 0,
     'no-extra-semi': 2,
     'no-func-assign': 2,
     'no-inner-declarations': 2,
     'no-invalid-regexp': 2,
     'no-irregular-whitespace': 2,
     'no-obj-calls': 2,
     'no-prototype-builtins': 0,
     'no-regex-spaces': 2,
     'no-sparse-arrays': 2,
     'no-template-curly-in-string': 1,
     'no-unexpected-multiline': 2,
     'no-unreachable': 2,
     'no-unsafe-finally': 2,
     'no-unsafe-negation': 2,
     'use-isnan': 2,
     'valid-jsdoc':
      [ 2,
        { requireParamDescription: false,
          requireReturnDescription: false } ],
     'valid-typeof': 2,
     'accessor-pairs': 0,
     'array-callback-return': 2,
     'block-scoped-var': 0,
     'class-methods-use-this': 1,
     complexity: 0,
     'consistent-return': 0,
     curly: [ 2, 'multi-line' ],
     'default-case': 2,
     'dot-location': [ 2, 'property' ],
     'dot-notation': 2,
     eqeqeq: [ 2, 'allow-null' ],
     'guard-for-in': 2,
     'no-alert': 1,
     'no-caller': 2,
     'no-case-declarations': 2,
     'no-div-regex': 2,
     'no-else-return': 0,
     'no-empty-function': 0,
     'no-empty-pattern': 2,
     'no-eq-null': 0,
     'no-eval': 2,
     'no-extend-native': 2,
     'no-extra-bind': 2,
     'no-extra-label': 2,
     'no-fallthrough': 2,
     'no-floating-decimal': 2,
     'no-global-assign': 2,
     'no-implicit-coercion': 2,
     'no-implicit-globals': 2,
     'no-implied-eval': 2,
     'no-invalid-this': 0,
     'no-iterator': 2,
     'no-labels': 2,
     'no-lone-blocks': 2,
     'no-loop-func': 2,
     'no-magic-numbers': 0,
     'no-multi-spaces': 0,
     'no-multi-str': 2,
     'no-new-func': 2,
     'no-new-wrappers': 2,
     'no-new': 2,
     'no-octal-escape': 2,
     'no-octal': 2,
     'no-param-reassign': 0,
     'no-proto': 2,
     'no-redeclare': 2,
     'no-restricted-properties': 0,
     'no-return-assign': 2,
     'no-script-url': 2,
     'no-self-assign': 2,
     'no-self-compare': 2,
     'no-sequences': 2,
     'no-throw-literal': 2,
     'no-unmodified-loop-condition': 1,
     'no-unused-expressions': 2,
     'no-unused-labels': 2,
     'no-useless-call': 2,
     'no-useless-concat': 2,
     'no-useless-escape': 2,
     'no-void': 2,
     'no-warning-comments': [ 1, { terms: [ 'todo', 'fixme' ], location: 'anywhere' } ],
     'no-with': 2,
     radix: 2,
     'vars-on-top': 0,
     'wrap-iife': 2,
     yoda: [ 2, 'never' ],
     strict: [ 2, 'global' ],
     'init-declarations': 0,
     'no-catch-shadow': 0,
     'no-delete-var': 2,
     'no-label-var': 2,
     'no-restricted-globals': 0,
     'no-shadow-restricted-names': 2,
     'no-shadow': 0,
     'no-undef-init': 2,
     'no-undef': 2,
     'no-undefined': 2,
     'no-unused-vars': 1,
     'no-use-before-define': 2,
     'callback-return': 0,
     'global-require': 0,
     'handle-callback-err': 2,
     'no-mixed-requires': 2,
     'no-new-require': 2,
     'no-path-concat': 2,
     'no-process-env': 0,
     'no-process-exit': 0,
     'no-restricted-modules': 0,
     'no-sync': 1,
     'array-bracket-spacing': [ 2, 'never' ],
     'block-spacing': [ 2, 'always' ],
     'brace-style': [ 2, 'stroustrup', { allowSingleLine: true } ],
     camelcase: 2,
     'comma-dangle': [ 2, 'never' ],
     'comma-spacing': [ 2, { before: false, after: true } ],
     'comma-style': [ 2, 'last' ],
     'computed-property-spacing': [ 2, 'never' ],
     'consistent-this': 0,
     'eol-last': 2,
     'func-call-spacing': [ 2, 'never' ],
     'func-name-matching': 0,
     'func-names': 0,
     'func-style': [ 1, 'declaration' ],
     'id-blacklist': 0,
     'id-length': 0,
     'id-match': 0,
     indent:
      [ 2,
        'tab',
        { SwitchCase: 1,
          VariableDeclarator: 0,
          outerIIFEBody: 1,
          MemberExpression: 1,
          FunctionDeclaration: { body: 1, parameters: 0 },
          FunctionExpression: { body: 1, parameters: 0 } } ],
     'jsx-quotes': [ 2, 'prefer-double' ],
     'key-spacing': [ 2, { beforeColon: false, afterColon: true } ],
     'keyword-spacing': [ 2 ],
     'line-comment-position': 0,
     'linebreak-style': [ 2, 'unix' ],
     'lines-around-comment': [ 2, { beforeBlockComment: true, allowBlockStart: true } ],
     'lines-around-directive': [ 2, { before: 'never', after: 'always' } ],
     'max-depth': 0,
     'max-len': 0,
     'max-lines': 0,
     'max-nested-callbacks': 0,
     'max-params': [ 1, 4 ],
     'max-statements-per-line': [ 1, { max: 1 } ],
     'max-statements': 0,
     'multiline-ternary': 0,
     'new-cap': 0,
     'new-parens': 2,
     'newline-after-var': 0,
     'newline-per-chained-call': 0,
     'no-array-constructor': 2,
     'no-bitwise': 2,
     'no-continue': 0,
     'no-inline-comments': 0,
     'no-lonely-if': 2,
     'no-mixed-operators': 2,
     'no-mixed-spaces-and-tabs': 2,
     'no-multiple-empty-lines': 0,
     'no-negated-condition': 0,
     'no-nested-ternary': 0,
     'no-new-object': 2,
     'no-plusplus': 0,
     'no-restricted-syntax': 0,
     'no-tabs': 0,
     'no-ternary': 0,
     'no-trailing-spaces': 2,
     'no-underscore-dangle': 0,
     'no-unneeded-ternary': 2,
     'no-whitespace-before-property': 2,
     'object-curly-newline': [ 0, { multiline: true } ],
     'object-curly-spacing': 0,
     'one-var': 0,
     'one-var-declaration-per-line': 0,
     'operator-assignment': [ 2, 'always' ],
     'operator-linebreak': 0,
     'padded-blocks': 0,
     'quote-props': [ 2, 'consistent-as-needed' ],
     quotes: [ 2, 'single', 'avoid-escape' ],
     'require-jsdoc': 0,
     'semi-spacing': [ 2, { before: false, after: true } ],
     semi: [ 2, 'never' ],
     'sort-keys': 0,
     'sort-vars': 0,
     'space-before-blocks': [ 2, 'always' ],
     'space-before-function-paren': [ 2, 'always' ],
     'space-in-parens': 0,
     'space-infix-ops': 2,
     'space-unary-ops': 2,
     'spaced-comment': 2,
     'unicode-bom': [ 2, 'never' ],
     'wrap-regex': 2,
     'arrow-body-style': [ 2, 'as-needed' ],
     'arrow-parens': [ 2, 'always' ],
     'arrow-spacing': 2,
     'constructor-super': 2,
     'generator-star-spacing': [ 2, 'before' ],
     'no-class-assign': 2,
     'no-confusing-arrow': 2,
     'no-const-assign': 2,
     'no-dupe-class-members': 2,
     'no-duplicate-imports': 1,
     'no-new-symbol': 2,
     'no-restricted-imports': 0,
     'no-this-before-super': 2,
     'no-useless-computed-key': 2,
     'no-useless-constructor': 2,
     'no-useless-rename': 2,
     'no-var': 0,
     'object-shorthand': [ 2, 'never' ],
     'prefer-arrow-callback': 0,
     'prefer-const': 0,
     'prefer-numeric-literals': 2,
     'prefer-reflect': 0,
     'prefer-rest-params': 0,
     'prefer-spread': 0,
     'prefer-template': 0,
     'require-yield': 2,
     'rest-spread-spacing': [ 2, 'never' ],
     'sort-imports': 0,
     'symbol-description': 2,
     'template-curly-spacing': [ 2, 'never' ],
     'yield-star-spacing': [ 2, 'both' ],
     'babel/new-cap': 2,
     'babel/object-curly-spacing': 0 },
  parser: 'typescript-eslint-parser' }

The dev deps:

  "devDependencies": {
    "@babel/cli": "^7.1.5",
    "@babel/core": "^7.1.6",
    "@babel/plugin-proposal-class-properties": "^7.1.0",
    "@babel/plugin-proposal-object-rest-spread": "^7.0.0",
    "@babel/preset-env": "^7.1.6",
    "@babel/preset-typescript": "^7.1.0",
    "eslint": "^5.9.0",
    "eslint-plugin-babel": "^5.3.0",
    "eslint-plugin-typescript": "^0.13.0",
    "typescript": "^3.1.6",
    "typescript-eslint-parser": "^21.0.1"
  },

And the eslint run:

npx eslint --fix './source/**

Rule for spacing around punctuation in types

Possibly as part of type-annotation-spacing, possible as a new rule. Right now, the punctuation that I can think of are | (union), & (intersection), [] (array or tuple), and {} (anonymous object definition).

The obvious preferences I can see for | and & are no-spaces (string|number) and spaces (string | number). Tuples and anonymous types are a bit different -- the two relevant spaces are after [ and before ], but not before [ or after ]. A more real-world-y example might be:

type keyedEntity = baseEntity & { primaryKey: string|number; records: [ number, string ][]; };

This could be formatted a number of different ways.

[no-parameter-properties] Support enforcing the inverse

The no-parameter-properties rule enforces not using parameter properties, but I would like to enforce use of parameter properties whenever possible. I actually like the shorthand.

I would suggest renaming the rule to parameter-properties (without the no- prefix) and support enforcing both use and non-use of parameter properties.


Relevant TSLint issue: palantir/tslint#2638

Indentation warning for properties of argument object

This issue was initially reported here: eslint/typescript-eslint-parser#458


What version of TypeScript are you using?
2.7.1

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

What code were you trying to parse?

const registration = (
  state: RegistrationStoreState = initialState,
  action: {
    type: string;
    data: Object;
    error: Object;
  }
) => {
...
}

What did you expect to happen?
To see clear worskpace without warning

What happened?

I see warning [eslint] Expected indentation of 2 spaces but found 4. (indent)
And only when I format this code in this way:


const registration = (
  state: RegistrationStoreState = initialState,
  action: {
  type: string;
  data: Object;
  error: Object;
  }
) => {
...
}

I don't see warnings.

"declare global" prevents accessing parent scope (no-undef)

This issue was initially reported here: eslint/typescript-eslint-parser#579


What version of TypeScript are you using?
3.1.3

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

What code were you trying to parse?

import React from 'react';

declare global {
  interface Global {
    __r: typeof React;
  }
}

// To complement `global.__r = React;`

What did you expect to happen?
No lint errors

What happened?

6:18 error 'React' is not defined no-undef

typescript-eslint-parser/analyze-scope.js:Referencer.visitGlobalAugmentation seems to replace the current scope with the global one, which makes accessing React in the above example
incorrectly say it's not defined.

@mysticatea (via #540): what case does visitGlobalAugmentation solve?

Parser disables react/no-unused-prop-types

This issue was initially reported here: eslint/typescript-eslint-parser#502


What version of TypeScript are you using?
2.9.2

What version of typescript-eslint-parser are you using?
16.0.1. Here are the other versions:

"eslint-config-airbnb": "17.0.0",
    "eslint-config-prettier": "2.9.0",
    "eslint-plugin-babel": "5.1.0",
    "eslint-plugin-import": "2.13.0",
    "eslint-plugin-jest": "21.15.0",
    "eslint-plugin-jsx-a11y": "6.1.1",
    "eslint-plugin-prettier": "2.6.2",
    "eslint-plugin-promise": "3.8.0",
    "eslint-plugin-react": "7.10.0",
    "eslint-plugin-typescript": "0.12.0",

What code were you trying to parse?

import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { ChapterShape, VerseShape } from '../../shapes';
import VerseContainer from '../../containers/VerseContainer';

const propTypes = {
  chapter: ChapterShape.isRequired,
  isEndOfSurah: PropTypes.bool.isRequired,
  currentVerse: PropTypes.string,
  isLoading: PropTypes.bool.isRequired,
  isSingleVerse: PropTypes.bool.isRequired,
  verses: PropTypes.objectOf(VerseShape),
  extra: PropTypes.bool.isRequired,
};

type Props = {
  chapter: ChapterShape;
  verses: { [verseKey: string]: VerseShape };
};

const ListView: React.SFC<Props> = ({ chapter, verses }: Props) => (
  <Fragment>
    {Object.values(verses).map((verse: VerseShape) => (
      <VerseContainer
        verse={verse}
        chapter={chapter}
        key={`${verse.chapterId}-${verse.id}-verse`}
      />
    ))}
  </Fragment>
);

ListView.propTypes = propTypes;

export default ListView;

What did you expect to happen?
I should get error for extra as 'extra' PropType is defined but prop is never used. This only works when I don't use typescript-eslint-parser.

What happened?

Notice: First release under the @typescript-eslint scope this weekend

Thanks so much to everyone for following along on the progress.

This weekend we will be releasing the first version from the monorepo, with the packages being under the new @typescript-eslint/ scope.

If you were already using the latest version of all of the separate tools, then there will not be a ton of updates for you, but there will be some.

Thanks! ❀️

[class-methods-use-this] Prevent false positives with classes

I think it would be benefit to have a rule similar to typescript/no-unused-vars to prevent class-methods-use-this from triggering on class methods where the method in base class (or additionally one of its descendants) doesn't use this, but one of the (other) subclasses does. For example, an abstract class may implement a method as just returning a default value, but the intention of the method is that some/most subclasses will have a concrete implementation that does use this.

no-extra-parens error when doing a type assertion

This issue was initially reported here: eslint/typescript-eslint-parser#465


What version of TypeScript are you using?

2.8.1

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

14.0.0

What code were you trying to parse?

t.true((me.get as SinonStub).calledWithExactly('/foo', other));

What did you expect to happen?

ESLint should not complain.

What happened?

error | Gratuitous parentheses around expression | no-extra-parens

Disallow implicit boolean casting of strings and numbers

It'd be great to have a lint rule that disallows (possible) strings and numbers from being implicitly converted to booleans:

const str: string | null = ''
if (str) {
  // ignores the empty string, the programmer likely attempted to guard against null
}

const num: number | undefined = 0
if (!num) {
  // ignores the 0 value, but the programmer likely attempted to guard against undefined
}

Besides if statements this would apply to ternary statements as well as &&, || and ! operators.

For the above examples passing code could be:

const str: string | null = ''
if (typeof str === 'string') {
  // …
}
if (str !== null) {
  // …
}

const num: number | undefined = 0
if (typeof num !== 'undefined') {
  // ...
}

I can see a stricter version of this rule which enforces explicit conversions even if a value can only be a string or number.

Provide documentation for writing eslint rules in typescript

Currently theres a bunch of rules at https://github.com/bradzacher/eslint-plugin-typescript written in js that, since they're operating on typescript should eventually be migrated to be written in typescript as per the comment https://github.com/bradzacher/eslint-plugin-typescript/issues/56#issuecomment-455313509.

I think a good first step here would be to:

  1. Figure out how the typing works for writing rules in typescript - I still haven't gotten my head around where all the types come from since some are from ESTree, some are from the JSX spec, and then some will be typescript specific

  2. Create or update ESUtils to be typescript so that it can provide typeguards as helper functions - for example isJSXAttribute(node), similar to how https://github.com/ajafff/tsutils works at the moment.

[no-unused-vars] false positive when generic param name masks name in parent scope

Repro

{
  "rules": {
    "no-unused-vars": "off",
    "typescript/no-unused-vars": "error"
  }
}
type Foo = number

function test<Foo>(bar: Foo) {
    return bar
}

Expected Result
error that type Foo is not defined

Actual Result
all is good

Additional Info

There is few issues there:

  • markVariableAsUsed is iterating over all variables even if found first one,
  • type parameters are not validated

Versions

package version
eslint-plugin-typescript 1.0.0-rc.1
typescript-eslint-parser internal
typescript 3.1.1

Install packages as git dependency

Hello all,

I am wondering how I depend on the the various packages from git in this new monorepo as currently I depend on master for both eslint-plugin-typescript and typescript-eslint-parser.

Thanks,

Corbin

[no-unused-vars] More missing detections

Repro

Run the linter on https://github.com/milesj/beemo

Some examples of it not working:

11:32  warning  'DriverContext' is defined but never used    no-unused-vars
6:10  warning  'Tool' is defined but never used          no-unused-vars
7:10  warning  'ExecaReturns' is defined but never used  no-unused-vars
  8:18  warning  'DriverArgs' is defined but never used  no-unused-vars
  9:10  warning  'BabelArgs' is defined but never used   no-unused-vars
  6:8  warning  'webpack' is defined but never used  no-unused-vars

Expected Result

They don't fail.

Actual Result

They do fail.

Additional Info

Versions

package version
eslint-plugin-typescript 0.14.0
typescript-eslint-parser 21.0.2
typescript 3.2.2

Question: How to get access type variables from scope

This issue was initially reported here: eslint/typescript-eslint-parser#566


I'm unsure if its supported yet, but in eslint scope contains informations about variables declared in it, but i'm unable to find types.

we have node: TSTypeParameterDeclaration -> TSTypeParameter but rather than iterating over all of them and checking if scope is same i don't see easier way to do so.

it will be nice if we could extend scopeManager and add information about this there.

If i'm wrong please correct me :>

[no-explicit-any] ignores generic in function definition

Repro

function test<T extends Partial<any>>() {}

const test = <T extends Partial<any>>() => {};

Expected Result
any should not be allowed there with the rule no-explicit-any enabled.
Actual Result
any is not detected.

Versions

package version
eslint-plugin-typescript 0.14.0
typescript-eslint-parser 21.0.2
typescript 3.2.2

The naming of the eslint-plugin seems to be incorrect

The documentation for the eslint-plugin still uses "plugins": ["typescript"] for the import staatement and "typescript/rule-name": "error" for using the rules. However, with the current package name of @typescript-eslint/eslint-plugin, this does not work.

The import statement should be "plugins": ["@typescript-eslint/eslint-plugin"] and the rule usage would be: "@typescript-eslint/rule-name": "error".

That being said, ESLint seemss to be opinionated about package naming. According to their documentation, the package should be named @typescript-eslint/eslint-plugin-typescript or something similar. (@<scope>/eslint-plugin-<plugin-name>).

Versions

package version
@typescript-eslint/eslint-plugin 0.2.1
@typescript-eslint/parser 0.2.1
typescript 0.2.1

[typescript/no-unused-vars] errors inside declare namespace

Repro
See below

{
  "rules": {
    "no-unused-vars": "off",
    "typescript/no-unused-vars": ["error", { "vars": "all", "args": "none" }]
  }
}
export = CodeMirror;
export as namespace CodeMirror;

declare function CodeMirror(host: HTMLElement, options?: CodeMirror.EditorConfiguration): CodeMirror.Editor;

declare namespace CodeMirror {
    function countColumn(line: string, index: number | null, tabSize: number): number;
    var version: string;
}

Expected Result
No errors.

Actual Result
typescript/no-unused-vars errors for function countColumn and version.

Additional Info

Versions

package version
eslint-plugin-typescript 1.0.0-rc.0
typescript-eslint-parser eslint-plugin-typescript/parser
typescript 3.1.6

Test failures with eslint 5.11

This issue was initially reported here: eslint/typescript-eslint-parser#585


What version of TypeScript are you using?
3.2.1

What version of typescript-eslint-parser are you using?
eslint/typescript-eslint-parser#584

This may not at all be important however I did notice that if I bump eslint to the latest version the test suite fails.

jest "--updateSnapshot"

 PASS  tests/lib/jsx.js
 FAIL  tests/lib/tsx.js
  ● TSX β€Ί if the filename ends with '.tsx', enable jsx option automatically. β€Ί filePath was not provided

    expect(received).toStrictEqual(expected)

    Expected value to equal:
      [{"column": 18, "fatal": true, "line": 1, "message": "Parsing error: '>' expected.", "ruleId": null, "severity": 2, "source": "const element = <T/>"}]
    Received:
      [{"column": 18, "fatal": true, "line": 1, "message": "Parsing error: '>' expected.", "ruleId": null, "severity": 2}]

    Difference:

    - Expected
    + Received

    @@ -4,8 +4,7 @@
          "fatal": true,
          "line": 1,
          "message": "Parsing error: '>' expected.",
          "ruleId": null,
          "severity": 2,
    -     "source": "const element = <T/>",
        },
      ]

      55 |             const messages = linter.verify(code, config);
      56 |
    > 57 |             expect(messages).toStrictEqual([{
         |                              ^
      58 |                 column: 18,
      59 |                 fatal: true,
      60 |                 line: 1,

      at Object.toStrictEqual (tests/lib/tsx.js:57:30)

  ● TSX β€Ί if the filename ends with '.tsx', enable jsx option automatically. β€Ί test.ts

    expect(received).toStrictEqual(expected)

    Expected value to equal:
      [{"column": 18, "fatal": true, "line": 1, "message": "Parsing error: '>' expected.", "ruleId": null, "severity": 2, "source": "const element = <T/>"}]
    Received:
      [{"column": 18, "fatal": true, "line": 1, "message": "Parsing error: '>' expected.", "ruleId": null, "severity": 2}]

    Difference:

    - Expected
    + Received

    @@ -4,8 +4,7 @@
          "fatal": true,
          "line": 1,
          "message": "Parsing error: '>' expected.",
          "ruleId": null,
          "severity": 2,
    -     "source": "const element = <T/>",
        },
      ]

      86 |             const messages = linter.verify(code, config, { filename: "test.ts" });
      87 |
    > 88 |             expect(messages).toStrictEqual([{
         |                              ^
      89 |                 column: 18,
      90 |                 fatal: true,
      91 |                 line: 1,

      at Object.toStrictEqual (tests/lib/tsx.js:88:30)

  ● TSX β€Ί if the filename ends with '.tsx', enable jsx option automatically. β€Ί test.ts with 'jsx:true' option

    expect(received).toStrictEqual(expected)

    Expected value to equal:
      [{"column": 18, "fatal": true, "line": 1, "message": "Parsing error: '>' expected.", "ruleId": null, "severity": 2, "source": "const element = <T/>"}]
    Received:
      [{"column": 18, "fatal": true, "line": 1, "message": "Parsing error: '>' expected.", "ruleId": null, "severity": 2}]

    Difference:

    - Expected
    + Received

    @@ -4,8 +4,7 @@
          "fatal": true,
          "line": 1,
          "message": "Parsing error: '>' expected.",
          "ruleId": null,
          "severity": 2,
    -     "source": "const element = <T/>",
        },
      ]

      107 |             const messages = linter.verify(code, config, { filename: "test.ts" });
      108 |
    > 109 |             expect(messages).toStrictEqual([{
          |                              ^
      110 |                 column: 18,
      111 |                 fatal: true,
      112 |                 line: 1,

      at Object.toStrictEqual (tests/lib/tsx.js:109:30)

 PASS  tests/lib/scope-analysis.js
 FAIL  tests/lib/basics.js
  ● basics β€Ί https://github.com/eslint/typescript-eslint-parser/issues/476

    expect(received).toStrictEqual(expected)

    Expected value to equal:
      [{"column": 21, "endColumn": 42, "endLine": 2, "line": 2, "message": "called on React.SFC", "nodeType": "TSTypeReference", "ruleId": "test", "severity": 2, "source": "export const Price: React.SFC<PriceProps> = function Price(props) {}"}, {"column": 31, "endColumn": 41, "endLine": 2, "line": 2, "message": "called on PriceProps", "nodeType": "TSTypeReference", "ruleId": "test", "severity": 2, "source": "export const Price: React.SFC<PriceProps> = function Price(props) {}"}]
    Received:
      [{"column": 21, "endColumn": 42, "endLine": 2, "line": 2, "message": "called on React.SFC", "nodeType": "TSTypeReference", "ruleId": "test", "severity": 2}, {"column": 31, "endColumn": 41, "endLine": 2, "line": 2, "message": "called on PriceProps", "nodeType": "TSTypeReference", "ruleId": "test", "severity": 2}]

    Difference:

    - Expected
    + Received

    @@ -6,19 +6,17 @@
          "line": 2,
          "message": "called on React.SFC",
          "nodeType": "TSTypeReference",
          "ruleId": "test",
          "severity": 2,
    -     "source": "export const Price: React.SFC<PriceProps> = function Price(props) {}",
        },
        Object {
          "column": 31,
          "endColumn": 41,
          "endLine": 2,
          "line": 2,
          "message": "called on PriceProps",
          "nodeType": "TSTypeReference",
          "ruleId": "test",
          "severity": 2,
    -     "source": "export const Price: React.SFC<PriceProps> = function Price(props) {}",
        },
      ]

      67 |         const messages = linter.verify(code, config, { filename: "issue.ts" });
      68 |
    > 69 |         expect(messages).toStrictEqual([
         |                          ^
      70 |             {
      71 |                 column: 21,
      72 |                 endColumn: 42,

      at Object.toStrictEqual (tests/lib/basics.js:69:26)

[no-object-literal-type-assertion] False positive when asserting function argument

Repro

module.exports = {
    root: true,
    plugins: ["typescript"],
    parser: "typescript-eslint-parser",
    extends: ["plugin:typescript/recommended"],
}
interface Foo {
    foo?: number;
}

function print(x: Foo): void {
    console.log(x.foo)
}

print({ bar: 5 } as Foo)

Expected Result

No errors.

Actual Result

/Users/semenov/tmp/ts-rule/test.ts
  9:7  error  Type assertion on object literals is forbidden, use a type annotation instead  typescript/no-object-literal-type-assertion

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

Additional Info

The primary purpose of the rule (as I see it) is to prevent object assignment such as const x = { ... } as T; which is better rewritten as const x: T = { ...};, but the rule disallows all other legitimate uses.

Versions

package version
eslint-plugin-typescript 1.0.0-rc.2
typescript-eslint-parser 21.0.2
typescript 3.2.2

parserOptions.ecmaFeatures.jsx option not passed to estree

This issue was initially reported here: eslint/typescript-eslint-parser#594


What version of TypeScript are you using?
3.1.1

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

What code were you trying to parse?

const RuleTester = require("eslint").RuleTester;

const ruleTester = new RuleTester({
    parserOptions: {
        ecmaVersion: 6,
        sourceType: "module",
        ecmaFeatures: {
            jsx: true,
        },
    },
    parser: "typescript-eslint-parser",
});

ruleTester.run("no-unused-vars", rule, {
    valid: [
		`
const Foo = function () {}
function render() {
    return (<Foo />);
}
		`,
	],
	invalid: [],
})

What did you expect to happen?
The code should parse successfully, so I can test the rule.

What happened?
Parsing error: \'>\' expected.

see astexplorer repl
Note the parser has the jsx option set to true

Use snapshots for testing rules

We should use a snapshot system to test rules with each rule having a rule-name.ts fixture that is run through ESLint. Config can be provided by inline /* eslint */ comments, and any reported errors would be dumped to either a Jest snapshot or an errors.json file. We could either switch the test framework from Mocha to Jest or just import Jest’s expect function to get access to the toMatchSnapshot matcher.

[no-useless-constructor] / [no-empty-function] with mixed JS & TS codebase

(This issue was originally raised in eslint/typescript-eslint-parser#418; and it was suggested that it would be more appropriately logged here, as it is not something that the parser can handle)

What version of TypeScript are you using?
2.6.2

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

What code were you trying to parse?

export default class Foo {
  constructor(private name: string) {}

  get greeting() : string {
    return `Hello ${this.name}`;
  }
}

What did you expect to happen?
No errors/warnings about empty constructor.

What happened?

  2:2   error  Useless constructor           no-useless-constructor
  2:36  error  Unexpected empty constructor  no-empty-function

For now, I have turned off these two rules in my .ts projects; but for projects that mix *.ts and *.js code, it would be nice to be able to have these rules enabled to catch any useless constructors/empty functions in *.js code without it also warning about valid *.ts constructors.

Indentation in decorators not working properly

This issue was initially reported here: eslint/typescript-eslint-parser#438


What version of TypeScript are you using?
2.6.2

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

What code were you trying to parse?

import { Component, Vue } from 'vue-property-decorator'
import TForm from '@components/t-form.vue'

@Component({
  components: {
    't-form': TForm
  }
})
export default class extends Vue {

What did you expect to happen?
No linting errors

What happened?
Got the following errors

import { Component, Vue } from 'vue-property-decorator'
import TForm from '@components/t-form.vue'

@Component({
  components: {
    't-form': TForm    <--- *** Expected indentation of 2 spaces but found 4  indent ***
  }
})    <--- *** Expected indentation of 2 spaces but found 0  indent ***
export default class extends Vue {

no-implicit-globals regression starting with v21.0.0

This issue was initially reported here: eslint/typescript-eslint-parser#587


What version of ESLint are you using?
5.11.1

What version of TypeScript are you using?
3.1.1

What version of typescript-eslint-parser are you using?
Any version from 21.0.0 onwards

What code were you trying to parse?

{
  "parser": "typescript-eslint-parser",
  "rules": {
    "func-style": ["error", "declaration"],
    "no-implicit-globals": "error"
  }
}
function foo() {
  return "bar";
}

module.exports = foo;

What did you expect to happen?
No errors

What happened?
In `[email protected], code passes with no errors.

With `[email protected] onwards, the errors below occur:

1:1  error  Implicit global variable, assign as global property instead  no-implicit-globals

Improve documentation for `typescript/no-unused-vars`

There are several use cases typescript/no-unused-vars does not yet support, such as type declarations:

type Foo = string;
// unexpected error
const foo: Foo = 'foo';

Would it be possible to track the status of this somewhere in the documentation? The docs for typescript/no-unused-vars do not make any mention of this.

I would be happy to raise a PR, but I don't know the full details of what is and isn't supported.

[no-redeclare] error for declare namespace

Repro
See below.

{
  "rules": {
    "no-redeclare": "error"
  }
}
export = CodeMirror;
export as namespace CodeMirror;

declare function CodeMirror(host: HTMLElement, options?: CodeMirror.EditorConfiguration): CodeMirror.Editor;

declare namespace CodeMirror {
}

Expected Result
No error.

Actual Result
no-redeclare error for declare namespace CodeMirror line.

Additional Info

Versions

package version
eslint-plugin-typescript 1.0.0-rc.0
typescript-eslint-parser eslint-plugin-typescript/parser
typescript 3.1.6

TSAbstractClassDeclaration are not defined in the scope (no-undef)

This issue was initially reported here: eslint/typescript-eslint-parser#578


What version of TypeScript are you using?
3.1.3

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

What code were you trying to parse?

export abstract class Foo {}
export class FooBar extends Foo {}

What did you expect to happen?
No lint errors

What happened?

2:29 error 'Foo' is not defined no-undef

While I understand that Typescript already has scope checks that seem to make no-undef unnecessary and can be disabled, it has been useful to ensure that name and length are not accidentally used, see: microsoft/TypeScript#18433

Potential Fix 1

eslint-scope/lib/referencer.js:Referencer.visitClass adds a definition into the scope for "ClassDeclaration", which does not happen for "TSAbstractClassDeclaration". I think this can be fixed by doing:

TSAbstractClassDeclaration(node) {
    this.currentScope().__define(
        node.id,
        new Definition("ClassName", node.id, node, null, null, null)
    );
    this.ClassDeclaration(node);
}

However this then causes:

1:23 error 'Foo' is already declared in the upper scope no-shadow

Because of this special casing of ClassDeclaration in eslint/lib/rules/no-shadow.js:

/**
 * Checks if a variable of the class name in the class scope of ClassDeclaration.
 *
 * ClassDeclaration creates two variables of its name into its outer scope and its class scope.
 * So we should ignore the variable in the class scope.
 *
 * @param {Object} variable The variable to check.
 * @returns {boolean} Whether or not the variable of the class name in the class scope of ClassDeclaration.
 */
function isDuplicatedClassNameVariable(variable) {
    const block = variable.scope.block;

    return block.type === "ClassDeclaration" && block.id === variable.identifiers[0];
}

From here, I suppose you could just say that no-shadow should be disabled on typescript files, in favor of using tslint's no-shadowed-variables

Potential Fix 2

In typescript-eslint-parser/parser.js, we can simply re-map the abstract class node:

case "TSAbstractClassDeclaration":
    node.type = 'ClassDeclaration';
    break;

which to me seems pretty clean, since as far as eslint is concerned, the abstract keyword doesn't affect anything.

indent rule ["error", 4] reports false positives in doc blocks

This issue was initially reported here: eslint/typescript-eslint-parser#474


Version 4.19.1

What code were you trying to parse?

/**
 * @param {string} name
 * @param {number} age
 * @returns {string}
 */
function foo(name: string, age: number): string {}

What did you expect to happen?
No indent error. This only occurs with the typescript-eslint-parser in combination with the eslint rule
'"indent": ["error", 4]'

What happened?
2:1 error Expected indentation of 0 spaces but found 3 indent
3:1 error Expected indentation of 0 spaces but found 3 indent
4:1 error Expected indentation of 0 spaces but found 3 indent

The error is shown by eslint, but after some research and checking existing issues #422.
The problem only occurs with "parser": "typescript-eslint-parser", in .eslint and in combination with "indent": ["error", 4].
Disabling the indent rule 'solves' the issue

Configuration with errors
.eslint

{
  "parser": "typescript-eslint-parser",
  "plugins": [
    "typescript"
  ],
  "parserOptions": {
    "sourceType": "module"
  },
  "rules": {
    "semi": ["error", "always"],
    "quotes": ["error", "double"],
    "indent": ["error", 4],
    "max-len": ["error", { "code": 120 }],
    "typescript/no-unused-vars": "error"
  }
}

tslint.json

{
  "defaultSeverity": "error",
  "extends": [
    "tslint:recommended"
  ],
  "jsRules": {},
  "rules": {
    "trailing-comma": [
      true,
      {
        "multiline": "never",
        "singleline": "never"
      }
    ],
    "object-literal-sort-keys": false,
    "variable-name": [
      true,
      "ban-keywords",
      "check-format",
      "allow-leading-underscore"
    ],
    "no-console": [true, "log"],
  },
  "rulesDirectory": []
}

packages

"dependencies": {
    "dotenv": "^5.0.1",
    "express": "^4.16.2",
    "express-graphql": "^0.6.12",
    "graphql": "^0.13.1",
    "mongodb": "^3.0.7"
  },
  "devDependencies": {
    "@types/bson": "^1.0.8",
    "@types/chai": "^4.1.3",
    "@types/express": "^4.11.0",
    "@types/graphql": "^0.12.7",
    "@types/mocha": "^2.2.46",
    "@types/mongodb": "^3.0.15",
    "@types/node": "^9.6.6",
    "chai": "^4.1.2",
    "eslint": "^4.19.1",
    "eslint-plugin-typescript": "^0.8.1",
    "mocha": "^5.1.1",
    "ts-node": "^4.1.0",
    "tslint": "^5.9.1",
    "typescript": "^2.8.3",
    "typescript-eslint-parser": "^15.0.0"
  }

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.