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

Commit

Permalink
no-unsafe-any: Allow import declarations
Browse files Browse the repository at this point in the history
  • Loading branch information
andy-hanson committed Apr 5, 2017
1 parent db83bfa commit 46e24da
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 8 deletions.
24 changes: 16 additions & 8 deletions src/rules/noUnsafeAnyRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,13 @@ export class Rule extends Lint.Rules.TypedRule {
const isExpression: (node: ts.Node) => node is ts.Expression = (ts as any).isExpression;

function walk(ctx: Lint.WalkContext<void>, checker: ts.TypeChecker): void {
return ts.forEachChild(ctx.sourceFile, recur);
function recur(node: ts.Node): void {
return ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {
if (isExpression(node) && isAny(checker.getTypeAtLocation(node)) && !isAllowedLocation(node, checker)) {
ctx.addFailureAtNode(node, Rule.FAILURE_STRING);
} else {
return ts.forEachChild(node, recur);
return ts.forEachChild(node, cb);
}
}
});
}

function isAllowedLocation(node: ts.Expression, { getContextualType, getTypeAtLocation }: ts.TypeChecker): boolean {
Expand All @@ -67,6 +66,13 @@ function isAllowedLocation(node: ts.Expression, { getContextualType, getTypeAtLo
// Allow casts
case ts.SyntaxKind.TypeAssertionExpression:
case ts.SyntaxKind.AsExpression:
// Allow imports
case ts.SyntaxKind.ImportEqualsDeclaration:
case ts.SyntaxKind.ExternalModuleReference:
case ts.SyntaxKind.ImportDeclaration:
case ts.SyntaxKind.NamespaceImport:
case ts.SyntaxKind.ImportSpecifier:
case ts.SyntaxKind.ImportClause:
return true;

// OK to pass 'any' to a function that takes 'any' as its argument
Expand All @@ -91,10 +97,12 @@ function isAllowedLocation(node: ts.Expression, { getContextualType, getTypeAtLo
return false;
}

// Allow `const x = foo;`, but not `const x: Foo = foo;`.
case ts.SyntaxKind.VariableDeclaration:
return Lint.hasModifier(parent.parent!.parent!.modifiers, ts.SyntaxKind.DeclareKeyword) ||
(parent as ts.VariableDeclaration).type === undefined;
// Allow `const x = foo;` and `const x: any = foo`, but not `const x: Foo = foo;`.
case ts.SyntaxKind.VariableDeclaration: {
const { name, type } = parent as ts.VariableDeclaration;
// Always allow the LHS to be `any`. Just don't allow RHS to be `any` when LHS isn't.
return node === name || type === undefined || type.kind === ts.SyntaxKind.AnyKeyword;
}

case ts.SyntaxKind.PropertyAccessExpression:
// Don't warn for right hand side; this is redundant if we warn for the left-hand side.
Expand Down
3 changes: 3 additions & 0 deletions test/rules/no-unsafe-any/commonjsModule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const x: any = 0;
namespace x {}
export = x;
3 changes: 3 additions & 0 deletions test/rules/no-unsafe-any/es6Module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const defaultExport: any = 0;
export default defaultExport;
export const namedExport: any = 0;
7 changes: 7 additions & 0 deletions test/rules/no-unsafe-any/test.ts.lint
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
import importEquals = require("./commonjsModule");
import importAlias = modA;
namespace N { const x: any = 0; }
import importQualifiedName = N.x;
import * as namespaceImport from "./commonjsModule";
import defaultExport, { namedExport } from "./es6Module";

declare const x: any;

function f(x: any) {
Expand Down

0 comments on commit 46e24da

Please sign in to comment.