Skip to content
This repository has been archived by the owner on Mar 25, 2021. It is now read-only.

Added NaN and (+/-)Infinity as numbers to no-inferrable-types #2885

Merged
merged 2 commits into from
Jul 7, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 6 additions & 3 deletions src/rules/noInferrableTypesRule.ts
Expand Up @@ -23,6 +23,8 @@ import * as Lint from "../index";
const OPTION_IGNORE_PARMS = "ignore-params";
const OPTION_IGNORE_PROPERTIES = "ignore-properties";

const INFINITY_TEXT = "Infinity";

interface Options {
ignoreParameters: boolean;
ignoreProperties: boolean;
Expand Down Expand Up @@ -77,7 +79,8 @@ class NoInferrableTypesWalker extends Lint.AbstractWalker<Options> {
const cb = (node: ts.Node): void => {
if (shouldCheck(node, this.options)) {
const { name, type, initializer } = node;
if (type !== undefined && initializer !== undefined && typeIsInferrable(type.kind, initializer.kind)) {
if (type !== undefined && initializer !== undefined
&& typeIsInferrable(type.kind, initializer.kind, initializer.getText())) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider passing initializer as parameter instead of calling getText()

const fix = Lint.Replacement.deleteFromTo(name.end, type.end);
this.addFailureAtNode(type, Rule.FAILURE_STRING_FACTORY(ts.tokenToString(type.kind)), fix);
}
Expand All @@ -104,12 +107,12 @@ function shouldCheck(node: ts.Node, { ignoreParameters, ignoreProperties }: Opti
}
}

function typeIsInferrable(type: ts.SyntaxKind, initializer: ts.SyntaxKind): boolean {
function typeIsInferrable(type: ts.SyntaxKind, initializer: ts.SyntaxKind, initializerText: string): boolean {
switch (type) {
case ts.SyntaxKind.BooleanKeyword:
return initializer === ts.SyntaxKind.TrueKeyword || initializer === ts.SyntaxKind.FalseKeyword;
case ts.SyntaxKind.NumberKeyword:
return initializer === ts.SyntaxKind.NumericLiteral;
return initializer === ts.SyntaxKind.NumericLiteral || initializerText.indexOf(INFINITY_TEXT) !== -1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A little helper to avoid getText(), handle negative numbers, Infinity, -Infinity, and NaN

function isNumeric(node: ts.Expression) {
    while (isPrefixUnaryExpression(node) &&
           (node.operator === ts.SyntaxKind.PlusToken || node.operator === ts.SyntaxKind.MinusToken)) {
        node = node.operand;
    }
    return node.kind === ts.SyntaxKind.NumericLiteral ||
        isIdentifier(node) && (node.text === "NaN" || node.text === "Infinity");
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. Side note: do we want to include "NaN" for this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the sake of consistency we should include NaN. Otherwise Infinity shouldn't be included either.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Also just noticed I missed an 'f' in the commit for your username. Whoops :)

case ts.SyntaxKind.StringKeyword:
switch (initializer) {
case ts.SyntaxKind.StringLiteral:
Expand Down
8 changes: 5 additions & 3 deletions test/rules/no-inferrable-types/default/test.ts.fix
@@ -1,7 +1,9 @@
// errors, inferrable type is declared
let x = 7;
let y = false;
let z = "foo";
let a = 7;
let b = false;
let c = "foo";
let d = Infinity;
let e = -Infinity;
class C {
x = 1;
}
Expand Down
10 changes: 7 additions & 3 deletions test/rules/no-inferrable-types/default/test.ts.lint
@@ -1,10 +1,14 @@
// errors, inferrable type is declared
let x: number = 7;
let a: number = 7;
~~~~~~ [number]
let y: boolean = false;
let b: boolean = false;
~~~~~~~ [boolean]
let z: string = "foo";
let c: string = "foo";
~~~~~~ [string]
let d: number = Infinity;
~~~~~~ [number]
let e: number = -Infinity;
~~~~~~ [number]
class C {
x: number = 1;
~~~~~~ [number]
Expand Down