diff --git a/packages/eslint-plugin/src/rules/no-unused-expressions.ts b/packages/eslint-plugin/src/rules/no-unused-expressions.ts index f7d86f50c1c7..b2eb6f8e30b7 100644 --- a/packages/eslint-plugin/src/rules/no-unused-expressions.ts +++ b/packages/eslint-plugin/src/rules/no-unused-expressions.ts @@ -12,10 +12,7 @@ export default util.createRule({ recommended: false, }, schema: baseRule.meta.schema, - messages: { - expected: - 'Expected an assignment or function call and instead saw an expression.', - }, + messages: {}, }, defaultOptions: [], create(context) { @@ -23,9 +20,13 @@ export default util.createRule({ return { ExpressionStatement(node): void { - if (node.expression.type === AST_NODE_TYPES.OptionalCallExpression) { + if ( + node.directive || + node.expression.type === AST_NODE_TYPES.OptionalCallExpression + ) { return; } + rules.ExpressionStatement(node); }, }; diff --git a/packages/eslint-plugin/tests/rules/no-unused-expressions.test.ts b/packages/eslint-plugin/tests/rules/no-unused-expressions.test.ts index 46653b30c663..feb3a584bcc3 100644 --- a/packages/eslint-plugin/tests/rules/no-unused-expressions.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unused-expressions.test.ts @@ -1,3 +1,4 @@ +import { TSESLint } from '@typescript-eslint/experimental-utils'; import rule from '../../src/rules/no-unused-expressions'; import { RuleTester } from '../RuleTester'; @@ -10,9 +11,11 @@ const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', }); +type TestCaseError = Omit, 'messageId'>; + // the base rule doesn't have messageIds function error( - messages: { line: number; column: number }[], + messages: TestCaseError[], // eslint-disable-next-line @typescript-eslint/no-explicit-any ): any[] { return messages.map(message => ({ @@ -42,6 +45,26 @@ ruleTester.run('no-unused-expressions', rule, { ` a?.['b']?.c(); `, + ` + module Foo { + 'use strict'; + } + `, + ` + namespace Foo { + 'use strict'; + + export class Foo {} + export class Bar {} + } + `, + ` + function foo() { + 'use strict'; + + return null; + } + `, ], invalid: [ { @@ -176,5 +199,56 @@ one.two?.three.four; }, ]), }, + { + code: ` +module Foo { + const foo = true; + 'use strict'; +} + `, + errors: error([ + { + line: 4, + endLine: 4, + column: 3, + endColumn: 16, + }, + ]), + }, + { + code: ` +namespace Foo { + export class Foo {} + export class Bar {} + + 'use strict'; +} + `, + errors: error([ + { + line: 6, + endLine: 6, + column: 3, + endColumn: 16, + }, + ]), + }, + { + code: ` +function foo() { + const foo = true; + + 'use strict'; +} + `, + errors: error([ + { + line: 5, + endLine: 5, + column: 3, + endColumn: 16, + }, + ]), + }, ], }); diff --git a/packages/typescript-estree/src/ts-estree/ts-estree.ts b/packages/typescript-estree/src/ts-estree/ts-estree.ts index afda76ead68d..1e473854029b 100644 --- a/packages/typescript-estree/src/ts-estree/ts-estree.ts +++ b/packages/typescript-estree/src/ts-estree/ts-estree.ts @@ -691,6 +691,7 @@ export interface ExportSpecifier extends BaseNode { export interface ExpressionStatement extends BaseNode { type: AST_NODE_TYPES.ExpressionStatement; expression: Expression; + directive?: string; } export interface ForInStatement extends BaseNode {