-
-
Notifications
You must be signed in to change notification settings - Fork 74
Discussion: Extending core ESLint rules to "just work" with TS-specific nodes #77
Description
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 definedinterface MyInterface {
bar: string,
baz: number
}
/* ESLint:
error, 'MyInterface' is not defined
error, 'bar' is not defined
error, 'baz' is not definedIt 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 usedThis 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 constructorRule: 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)