diff --git a/packages/eslint-plugin/src/rules/no-implied-eval.ts b/packages/eslint-plugin/src/rules/no-implied-eval.ts index 8c6d9bc74338..273cfd4d734c 100644 --- a/packages/eslint-plugin/src/rules/no-implied-eval.ts +++ b/packages/eslint-plugin/src/rules/no-implied-eval.ts @@ -4,7 +4,7 @@ import { getScope } from '@typescript-eslint/utils/eslint-utils'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; -import { createRule, getParserServices } from '../util'; +import { createRule, getParserServices, isFunctionSimilar } from '../util'; const FUNCTION_CONSTRUCTOR = 'Function'; const GLOBAL_CANDIDATES = new Set(['global', 'window', 'globalThis']); @@ -78,15 +78,8 @@ export default createRule({ return true; } - // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison - if (symbol && symbol.escapedName === FUNCTION_CONSTRUCTOR) { - const declarations = symbol.getDeclarations() ?? []; - for (const declaration of declarations) { - const sourceFile = declaration.getSourceFile(); - if (services.program.isSourceFileDefaultLibrary(sourceFile)) { - return true; - } - } + if (isFunctionSimilar(services.program, type)) { + return true; } const signatures = checker.getSignaturesOfType( @@ -143,13 +136,8 @@ export default createRule({ const type = services.getTypeAtLocation(node.callee); const symbol = type.getSymbol(); if (symbol) { - const declarations = symbol.getDeclarations() ?? []; - for (const declaration of declarations) { - const sourceFile = declaration.getSourceFile(); - if (services.program.isSourceFileDefaultLibrary(sourceFile)) { - context.report({ node, messageId: 'noFunctionConstructor' }); - return; - } + if (isFunctionSimilar(services.program, type)) { + context.report({ node, messageId: 'noFunctionConstructor' }); } } else { context.report({ node, messageId: 'noFunctionConstructor' }); diff --git a/packages/type-utils/src/builtinSymbolLikes.ts b/packages/type-utils/src/builtinSymbolLikes.ts index 3443a0d0382e..0a5cfa47a608 100644 --- a/packages/type-utils/src/builtinSymbolLikes.ts +++ b/packages/type-utils/src/builtinSymbolLikes.ts @@ -69,6 +69,18 @@ export function isReadonlyTypeLike( ); }); } +/** + * let F = new Function("foo"); + * ^ FunctionSimilar + * let I = (callback: Function) => {} + * ^ FunctionSimilar + */ +export function isFunctionSimilar(program: ts.Program, type: ts.Type): boolean { + return ( + isBuiltinSymbolLike(program, type, 'Function') || + isBuiltinSymbolLike(program, type, 'FunctionConstructor') + ); +} export function isBuiltinTypeAliasLike( program: ts.Program, type: ts.Type,