Skip to content
This repository was archived by the owner on Feb 21, 2022. It is now read-only.

Commit c2f242e

Browse files
committed
Fixed #22 and other minor fixes
1 parent 435555c commit c2f242e

File tree

7 files changed

+121
-211
lines changed

7 files changed

+121
-211
lines changed

README.md

Lines changed: 7 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@
44

55
You want to code in TypeScript but miss all the rules available in ESLint?
66

7-
Now you can combine both worlds by using this TSLint plugin.
7+
Now you can combine both worlds by using this TSLint plugin!
88

9+
*WARN: this project is still under development.*
910

10-
## Usage (it will be available only in v0.2.x)
11+
*You can see what see what rules were already migrated migrated [in the eslint_tsling.json file](https://github.com/buzinas/tslint-eslint-rules/blob/master/eslint_tslint.json)*
12+
13+
14+
## Usage [TODO](https://github.com/buzinas/tslint-eslint-rules/issues/23)
1115

1216
Install from NPM to your Dev Dependencies
1317

@@ -266,7 +270,7 @@ The following rules point out areas where you might have made mistakes.
266270
]
267271
```
268272

269-
* [valid-typeof](http://eslint.org/docs/rules/valid-typeof) => valid-typeof (tslint-eslint-rules) [TODO](https://github.com/buzinas/tslint-eslint-rules/issues/22)
273+
* [valid-typeof](http://eslint.org/docs/rules/valid-typeof) => valid-typeof (tslint-eslint-rules)
270274
* Description: Ensure that the results of typeof are compared against a valid string (recommended)
271275
* Usage
272276

@@ -2246,167 +2250,6 @@ The following rules are included for compatibility with [JSHint](http://jshint.c
22462250
]
22472251
```
22482252

2249-
### Removed
2250-
2251-
These rules existed in a previous version of ESLint but have since been replaced by newer rules.
2252-
2253-
* [generator-star](http://eslint.org/docs/rules/generator-star) =>
2254-
* Description: enforce the position of the `*` in generator functions (replaced by [generator-star-spacing](http://eslint.org/docs/rules/generator-star-spacing))
2255-
* Usage
2256-
2257-
```json
2258-
"generator-star": [
2259-
true,
2260-
{
2261-
2262-
}
2263-
]
2264-
```
2265-
* [global-strict](http://eslint.org/docs/rules/global-strict) =>
2266-
* Description: require or disallow the `"use strict"` pragma in the global scope (replaced by [strict](http://eslint.org/docs/rules/strict))
2267-
* Usage
2268-
2269-
```json
2270-
"global-strict": [
2271-
true,
2272-
{
2273-
2274-
}
2275-
]
2276-
```
2277-
* [no-comma-dangle](http://eslint.org/docs/rules/no-comma-dangle) =>
2278-
* Description: disallow trailing commas in object literals (replaced by [comma-dangle](http://eslint.org/docs/rules/comma-dangle))
2279-
* Usage
2280-
2281-
```json
2282-
"no-comma-dangle": [
2283-
true,
2284-
{
2285-
2286-
}
2287-
]
2288-
```
2289-
* [no-empty-class](http://eslint.org/docs/rules/no-empty-class) =>
2290-
* Description: disallow the use of empty character classes in regular expressions (replaced by [no-empty-character-class](http://eslint.org/docs/rules/no-empty-character-class))
2291-
* Usage
2292-
2293-
```json
2294-
"no-empty-class": [
2295-
true,
2296-
{
2297-
2298-
}
2299-
]
2300-
```
2301-
* [no-extra-strict](http://eslint.org/docs/rules/no-extra-strict) =>
2302-
* Description: disallow unnecessary use of `"use strict";` when already in strict mode (replaced by [strict](http://eslint.org/docs/rules/strict))
2303-
* Usage
2304-
2305-
```json
2306-
"no-extra-strict": [
2307-
true,
2308-
{
2309-
2310-
}
2311-
]
2312-
```
2313-
* [no-reserved-keys](http://eslint.org/docs/rules/no-reserved-keys) =>
2314-
* Description: disallow reserved words being used as object literal keys
2315-
* Usage
2316-
2317-
```json
2318-
"no-reserved-keys": [
2319-
true,
2320-
{
2321-
2322-
}
2323-
]
2324-
```
2325-
* [no-space-before-semi](http://eslint.org/docs/rules/no-space-before-semi) =>
2326-
* Description: disallow space before semicolon (replaced by [semi-spacing](http://eslint.org/docs/rules/semi-spacing))
2327-
* Usage
2328-
2329-
```json
2330-
"no-space-before-semi": [
2331-
true,
2332-
{
2333-
2334-
}
2335-
]
2336-
```
2337-
* [no-wrap-func](http://eslint.org/docs/rules/no-wrap-func) =>
2338-
* Description: disallow wrapping of non-IIFE statements in parens (replaced by [no-extra-parens](http://eslint.org/docs/rules/no-extra-parens))
2339-
* Usage
2340-
2341-
```json
2342-
"no-wrap-func": [
2343-
true,
2344-
{
2345-
2346-
}
2347-
]
2348-
```
2349-
* [space-after-function-name](http://eslint.org/docs/rules/space-after-function-name) =>
2350-
* Description: require a space after function names (replaced by [space-before-function-paren](http://eslint.org/docs/rules/space-before-function-paren))
2351-
* Usage
2352-
2353-
```json
2354-
"space-after-function-name": [
2355-
true,
2356-
{
2357-
2358-
}
2359-
]
2360-
```
2361-
* [space-before-function-parentheses](http://eslint.org/docs/rules/space-before-function-parentheses) =>
2362-
* Description: require or disallow space before function parentheses (replaced by [space-before-function-paren](http://eslint.org/docs/rules/space-before-function-paren))
2363-
* Usage
2364-
2365-
```json
2366-
"space-before-function-parentheses": [
2367-
true,
2368-
{
2369-
2370-
}
2371-
]
2372-
```
2373-
* [space-in-brackets](http://eslint.org/docs/rules/space-in-brackets) =>
2374-
* Description: require or disallow spaces inside brackets (replaced by [object-curly-spacing](http://eslint.org/docs/rules/object-curly-spacing) and [array-bracket-spacing](http://eslint.org/docs/rules/array-bracket-spacing))
2375-
* Usage
2376-
2377-
```json
2378-
"space-in-brackets": [
2379-
true,
2380-
{
2381-
2382-
}
2383-
]
2384-
```
2385-
* [space-unary-word-ops](http://eslint.org/docs/rules/space-unary-word-ops) =>
2386-
* Description: require or disallow spaces before/after unary operators (replaced by [space-unary-ops](http://eslint.org/docs/rules/space-unary-ops))
2387-
* Usage
2388-
2389-
```json
2390-
"space-unary-word-ops": [
2391-
true,
2392-
{
2393-
2394-
}
2395-
]
2396-
```
2397-
* [spaced-line-comment](http://eslint.org/docs/rules/spaced-line-comment) =>
2398-
* Description: require or disallow a space immediately following the `//` in a line comment (replaced by [spaced-comment](spaced-comment))
2399-
* Usage
2400-
2401-
```json
2402-
"spaced-line-comment": [
2403-
true,
2404-
{
2405-
2406-
}
2407-
]
2408-
```
2409-
24102253

24112254
## Contributing
24122255

eslint_tslint.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"rulesDirectory": "dist/rules",
3+
"rules": {
4+
"no-constant-condition": true,
5+
"valid-typeof": true
6+
}
7+
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "tslint-eslint-rules",
3-
"version": "0.1.0",
3+
"version": "0.1.1",
44
"description": "Improve your TSLint with the missing ESLint Rules",
55
"main": "index.js",
66
"scripts": {

src/rules/noConstantConditionRule.ts

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/// <reference path='../../node_modules/tslint/lib/tslint.d.ts' />
33

44
export class Rule extends Lint.Rules.AbstractRule {
5-
public static FAILURE_STRING = "Unexpected constant condition: ";
5+
public static FAILURE_STRING = 'Unexpected constant condition: ';
66

77
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
88
const walker = new NoConstantConditionWalker(sourceFile, this.getOptions());
@@ -25,7 +25,7 @@ class NoConstantConditionWalker extends Lint.RuleWalker {
2525

2626
protected visitDoStatement(node: ts.DoStatement) {
2727
this.validateConditionalExpression(node.expression);
28-
super.visitWhileStatement(node);
28+
super.visitDoStatement(node);
2929
}
3030

3131
protected visitForStatement(node: ts.ForStatement) {
@@ -42,49 +42,49 @@ class NoConstantConditionWalker extends Lint.RuleWalker {
4242

4343
private validateConditionalExpression(expression: ts.Expression) {
4444
this.isInConditional = true;
45-
if (isConstant(expression)) {
45+
if (this.isConstant(expression)) {
4646
this.addFailure(this.createFailure(expression.getStart(), expression.getWidth(), Rule.FAILURE_STRING));
4747
}
4848
// walk the children of the conditional expression for nested conditions
4949
this.walkChildren(expression);
5050
this.isInConditional = false;
5151
}
52-
}
53-
54-
function isConstant(node: ts.Node) {
55-
switch (node.kind) {
56-
// ESLint Literal
57-
case ts.SyntaxKind.StringLiteral:
58-
case ts.SyntaxKind.NumericLiteral:
59-
case ts.SyntaxKind.TrueKeyword:
60-
case ts.SyntaxKind.FalseKeyword:
61-
// ESLint ArrowFunctionExpression
62-
case ts.SyntaxKind.ArrowFunction:
63-
// ESLint FunctionExpression
64-
case ts.SyntaxKind.FunctionExpression:
65-
// ESLint ObjectExpression
66-
case ts.SyntaxKind.ObjectLiteralExpression:
67-
// ESLint ArrayExpression
68-
case ts.SyntaxKind.ArrayLiteralExpression:
69-
return true;
70-
// ESLint UnaryExpression
71-
case ts.SyntaxKind.PrefixUnaryExpression:
72-
case ts.SyntaxKind.PostfixUnaryExpression:
73-
return false; // TODO
74-
// ESLint BinaryExpression / LogicalExpression
75-
case ts.SyntaxKind.BinaryExpression:
76-
// ESLint AssignmentExpression
77-
if (isAssignmentToken((node as ts.BinaryExpression).operatorToken)) {
78-
return isConstant(node.getLastToken());
79-
}
80-
return isConstant(node.getFirstToken()) && isConstant(node.getLastToken());
81-
case ts.SyntaxKind.ConditionalExpression:
82-
return isConstant((node as ts.ConditionalExpression).condition);
52+
53+
private isConstant(node: ts.Node) {
54+
switch (node.kind) {
55+
// ESLint Literal
56+
case ts.SyntaxKind.StringLiteral:
57+
case ts.SyntaxKind.NumericLiteral:
58+
case ts.SyntaxKind.TrueKeyword:
59+
case ts.SyntaxKind.FalseKeyword:
60+
// ESLint ArrowFunctionExpression
61+
case ts.SyntaxKind.ArrowFunction:
62+
// ESLint FunctionExpression
63+
case ts.SyntaxKind.FunctionExpression:
64+
// ESLint ObjectExpression
65+
case ts.SyntaxKind.ObjectLiteralExpression:
66+
// ESLint ArrayExpression
67+
case ts.SyntaxKind.ArrayLiteralExpression:
68+
return true;
69+
// ESLint UnaryExpression
70+
case ts.SyntaxKind.PrefixUnaryExpression:
71+
case ts.SyntaxKind.PostfixUnaryExpression:
72+
return false; // TODO
73+
// ESLint BinaryExpression / LogicalExpression
74+
case ts.SyntaxKind.BinaryExpression:
75+
// ESLint AssignmentExpression
76+
if (this.isAssignmentToken((node as ts.BinaryExpression).operatorToken)) {
77+
return this.isConstant(node.getLastToken());
78+
}
79+
return this.isConstant(node.getFirstToken()) && this.isConstant(node.getLastToken());
80+
case ts.SyntaxKind.ConditionalExpression:
81+
return this.isConstant((node as ts.ConditionalExpression).condition);
82+
}
83+
84+
return false;
85+
}
86+
87+
private isAssignmentToken(token: ts.Node) {
88+
return token.kind >= ts.SyntaxKind.FirstAssignment && token.kind <= ts.SyntaxKind.LastAssignment;
8389
}
84-
85-
return false;
86-
}
87-
88-
function isAssignmentToken(token: ts.Node) {
89-
return token.kind >= ts.SyntaxKind.FirstAssignment && token.kind <= ts.SyntaxKind.LastAssignment;
9090
}

src/rules/validTypeofRule.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/// <reference path='../../node_modules/tslint/typings/typescriptServices.d.ts' />
2+
/// <reference path='../../node_modules/tslint/lib/tslint.d.ts' />
3+
4+
export class Rule extends Lint.Rules.AbstractRule {
5+
public static FAILURE_STRING = 'Invalid typeof comparison value: ';
6+
7+
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
8+
const walker = new ValidTypeofWalker(sourceFile, this.getOptions());
9+
return this.applyWithWalker(walker);
10+
}
11+
}
12+
13+
class ValidTypeofWalker extends Lint.RuleWalker {
14+
private VALID_TYPES = ['symbol', 'undefined', 'object', 'boolean', 'number', 'string', 'function'];
15+
private OPERATORS = [ts.SyntaxKind.EqualsEqualsToken, ts.SyntaxKind.EqualsEqualsEqualsToken, ts.SyntaxKind.ExclamationEqualsToken, ts.SyntaxKind.ExclamationEqualsEqualsToken];
16+
17+
protected visitNode(node: ts.Node) {
18+
if (node.kind === ts.SyntaxKind.TypeOfExpression) {
19+
this.validateTypeOf(node as ts.TypeOfExpression);
20+
}
21+
super.visitNode(node);
22+
}
23+
24+
private validateTypeOf(node: ts.TypeOfExpression) {
25+
if (node.parent.kind === ts.SyntaxKind.BinaryExpression) {
26+
let parent = (node.parent as ts.BinaryExpression);
27+
if (this.OPERATORS.indexOf(parent.operatorToken.kind) !== -1) {
28+
let sibling = parent.left === node ? parent.right : parent.left;
29+
30+
if (sibling.kind === ts.SyntaxKind.StringLiteral && this.VALID_TYPES.indexOf((sibling as ts.StringLiteral).text) === -1) {
31+
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING));
32+
}
33+
}
34+
}
35+
}
36+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/// <reference path='../../../typings/chai/chai.d.ts' />
2+
/// <reference path='../../../typings/mocha/mocha.d.ts' />
3+
4+
import {testScript} from './helper';
5+
import {expect} from 'chai';
6+
7+
const rule = 'valid-typeof';
8+
const scripts = {
9+
valid: `if (typeof foo === "string") {}
10+
if (typeof bar == 'undefined') {}
11+
if (typeof foo === baz) {}
12+
if (typeof bar === typeof qux) {}`,
13+
14+
invalid: `if (typeof foo === "strnig") {}
15+
if (typeof foo == "undefimed") {}
16+
if (typeof bar != 'nunber') {}
17+
if (typeof bar !== "fucntion") {}`
18+
};
19+
20+
describe('valid-oftype', function test() {
21+
it('should pass when using valid strings or variables', function testValid() {
22+
const res = testScript(rule, scripts.valid);
23+
expect(res).to.be.true;
24+
});
25+
26+
it('should fail when using invalid strings', function testInvalid() {
27+
const res = testScript(rule, scripts.invalid);
28+
expect(res).to.be.false;
29+
});
30+
});

tslint.json

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)