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 all commits
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
15 changes: 14 additions & 1 deletion src/language/utils.ts
Expand Up @@ -16,7 +16,7 @@
*/

import * as path from "path";
import { isBlockScopedVariableDeclarationList, isPrefixUnaryExpression } from "tsutils";
import { isBlockScopedVariableDeclarationList, isIdentifier, isPrefixUnaryExpression } from "tsutils";
import * as ts from "typescript";

import {IDisabledInterval, RuleFailure} from "./rule/rule"; // tslint:disable-line deprecation
Expand Down Expand Up @@ -218,6 +218,19 @@ export function isLoop(node: ts.Node): node is ts.IterationStatement {
|| node.kind === ts.SyntaxKind.ForOfStatement;
}

/**
* @returns Whether node is a numeric expression.
*/
export 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");
}

export interface TokenPosition {
/** The start of the token including all trivia before it */
fullStart: number;
Expand Down
11 changes: 6 additions & 5 deletions src/rules/noInferrableTypesRule.ts
Expand Up @@ -77,7 +77,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)) {
const fix = Lint.Replacement.deleteFromTo(name.end, type.end);
this.addFailureAtNode(type, Rule.FAILURE_STRING_FACTORY(ts.tokenToString(type.kind)), fix);
}
Expand All @@ -104,14 +105,14 @@ function shouldCheck(node: ts.Node, { ignoreParameters, ignoreProperties }: Opti
}
}

function typeIsInferrable(type: ts.SyntaxKind, initializer: ts.SyntaxKind): boolean {
function typeIsInferrable(type: ts.SyntaxKind, initializer: ts.Expression): boolean {
switch (type) {
case ts.SyntaxKind.BooleanKeyword:
return initializer === ts.SyntaxKind.TrueKeyword || initializer === ts.SyntaxKind.FalseKeyword;
return initializer.kind === ts.SyntaxKind.TrueKeyword || initializer.kind === ts.SyntaxKind.FalseKeyword;
case ts.SyntaxKind.NumberKeyword:
return initializer === ts.SyntaxKind.NumericLiteral;
return Lint.isNumeric(initializer);
case ts.SyntaxKind.StringKeyword:
switch (initializer) {
switch (initializer.kind) {
case ts.SyntaxKind.StringLiteral:
case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
case ts.SyntaxKind.TemplateExpression:
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