Repository: nzakas/eslint-plugin-typescript
Pull request #8 (2016-10-13 04:37:30)

New: Add rule no-any
Rule based off of TSLint's [no-any](https://palantir.github.io/tslint/rules/no-any/) rule

JamesHenry: Thanks for your continued efforts, @dannyfritz!

Could we go for `no-explicit-any` as the name of the rule?

I think it is a better explanation of what is actually being checked, and that was it is more clearly a complement to the TypeScript compiler flag `noImplicitAny`.

Could you also briefly touch on that relationship in your docs?
dannyfritz: Rebased and made changes. :)
JamesHenry: LGTM, thanks!

Patch:
diff --git a/README.md b/README.md
index bd81fa5..c4c7105 100644
--- a/README.md
+++ b/README.md
@@ -52,3 +52,4 @@ Then configure the rules you want to use under the rules section.
 * `typescript/type-annotation-spacing` - enforces one space after the colon and zero spaces before the colon of a type annotation.
 * `typescript/explicit-member-accessibility` - enforces accessibility modifiers on class properties and methods.
 * `typescript/no-triple-slash-reference` - enforces `/// <reference />` is not used.
+* `typescript/no-explicit-any` - enforces the any type is not used.
diff --git a/docs/rules/no-explicit-any.md b/docs/rules/no-explicit-any.md
new file mode 100644
index 0000000..bc365f6
--- /dev/null
+++ b/docs/rules/no-explicit-any.md
@@ -0,0 +1,45 @@
+# Enforces the any type is not used (no-explicit-any)
+
+Using the `any` type defeats the purpose of using TypeScript.
+When `any` is used, all compiler type checks around that value are ignored.
+
+## Rule Details
+
+This rule goes doesn't allow `any` types to be defined.
+It aims to keep TypeScript maximally useful.
+TypeScript has a compiler flag for `--noImplicitAny` that will prevent
+an `any` type from being implied by the compiler, but doesn't prevent
+`any` from being explicitly used.
+
+The following patterns are considered warnings:
+
+```ts
+const age : any = "seventeen"
+```
+
+```ts
+function greet () : any {}
+```
+
+The following patterns are not warnings:
+
+```ts
+const age : number = 17
+```
+
+```ts
+function greet () : string {}
+```
+
+## When Not To Use It
+
+If an unknown type or a library without typings is used
+and you want to be able to specify `any`.
+
+## Further Reading
+
+* TypeScript [any type](https://www.typescriptlang.org/docs/handbook/basic-types.html#any)
+
+## Compatibility
+
+* TSLint: [no-any](https://palantir.github.io/tslint/rules/no-any/)
diff --git a/lib/rules/no-explicit-any.js b/lib/rules/no-explicit-any.js
new file mode 100644
index 0000000..32b9a15
--- /dev/null
+++ b/lib/rules/no-explicit-any.js
@@ -0,0 +1,69 @@
+/**
+ * @fileoverview Enforces the any type is not used.
+ * @author Danny Fritz
+ */
+"use strict";
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = {
+    meta: {
+        docs: {
+            description: "Enforces the any type is not used.",
+            category: "TypeScript"
+        },
+        schema: []
+    },
+
+    create: function(context) {
+
+        //----------------------------------------------------------------------
+        // Helpers
+        //----------------------------------------------------------------------
+
+        /**
+         * Checks if the any type is used
+         * @param {ASTNode} typeAnnotation The TypeAnnotation node.
+         * @returns {void}
+         * @private
+         */
+        function checkTypeAnnotationForAny(typeAnnotation) {
+            if (typeAnnotation.typeAnnotation.type === "TSAnyKeyword") {
+                context.report({
+                    node: typeAnnotation,
+                    message: "Unexpected any. Specify a different type."
+                });
+            }
+        }
+
+        /**
+         * Checks if a function node used the any type
+         * @param {ASTNode} node The node representing a function.
+         * @returns {void}
+         * @private
+         */
+        function checkFunctionReturnTypeForAny(node) {
+            if (node.returnType) {
+                checkTypeAnnotationForAny(node.returnType);
+            }
+        }
+
+        //----------------------------------------------------------------------
+        // Public
+        //----------------------------------------------------------------------
+        return {
+
+            Identifier(node) {
+                if (node.typeAnnotation) {
+                    checkTypeAnnotationForAny(node.typeAnnotation);
+                }
+            },
+
+            FunctionDeclaration: checkFunctionReturnTypeForAny,
+            FunctionExpression: checkFunctionReturnTypeForAny,
+            ArrowFunctionExpression: checkFunctionReturnTypeForAny
+        };
+    }
+};


Test patch:
diff --git a/tests/lib/rules/no-explicit-any.js b/tests/lib/rules/no-explicit-any.js
new file mode 100644
index 0000000..73be9b2
--- /dev/null
+++ b/tests/lib/rules/no-explicit-any.js
@@ -0,0 +1,52 @@
+/**
+ * @fileoverview Enforces the any type is not used
+ * @author Danny Fritz
+ */
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+var rule = require("../../../lib/rules/no-explicit-any"),
+    RuleTester = require("eslint").RuleTester;
+
+
+//------------------------------------------------------------------------------
+// Tests
+//------------------------------------------------------------------------------
+
+var ruleTester = new RuleTester();
+ruleTester.run("no-explicit-any", rule, {
+
+    valid: [
+        {
+            code: "const number : number = 1",
+            parser: "typescript-eslint-parser"
+        },
+        {
+            code: "function greet () : string {}",
+            parser: "typescript-eslint-parser"
+        }
+    ],
+    invalid: [
+        {
+            code: "const number : any = 1",
+            parser: "typescript-eslint-parser",
+            errors: [{
+                message: "Unexpected any. Specify a different type.",
+                line: 1,
+                column: 16
+            }]
+        },
+        {
+            code: "function generic () : any {}",
+            parser: "typescript-eslint-parser",
+            errors: [{
+                message: "Unexpected any. Specify a different type.",
+                line: 1,
+                column: 23
+            }]
+        }
+    ]
+});