@@ -19,8 +19,11 @@ export interface Options {
1919/**
2020 * Functions whose arguments should not be checked for localization.
2121 * Supports wildcards: "console.*" matches console.log, console.error, etc.
22+ *
23+ * This list is intentionally minimal - Error constructors and console methods
24+ * are detected automatically via TypeScript types.
2225 */
23- const DEFAULT_IGNORE_FUNCTIONS = [ "console.*" , " require", "import" , "Error" , "TypeError" , "RangeError" , "SyntaxError "]
26+ const DEFAULT_IGNORE_FUNCTIONS = [ "require" , "import" ]
2427
2528/**
2629 * JSX attributes and object properties whose values should not be checked.
@@ -35,11 +38,9 @@ const DEFAULT_IGNORE_FUNCTIONS = ["console.*", "require", "import", "Error", "Ty
3538const DEFAULT_IGNORE_PROPERTIES = [
3639 // CSS class names - accept arbitrary strings, always technical
3740 "className" ,
38- "styleName" ,
39- // React-specific
41+ // React key prop
4042 "key" ,
41- // Testing IDs - arbitrary strings, always technical
42- "testID" ,
43+ // Testing ID - DOM Testing Library standard
4344 "data-testid"
4445]
4546
@@ -297,6 +298,86 @@ function isIgnoredFunctionArgument(node: TSESTree.Node, ignoreFunctions: string[
297298 return false
298299}
299300
301+ /**
302+ * Checks if a string is an argument to a Console method (console.log, etc.)
303+ * using TypeScript type information.
304+ */
305+ function isConsoleMethodArgument (
306+ node : TSESTree . Node ,
307+ typeChecker : ts . TypeChecker ,
308+ parserServices : ReturnType < typeof ESLintUtils . getParserServices >
309+ ) : boolean {
310+ const parent = node . parent
311+ if ( parent ?. type !== AST_NODE_TYPES . CallExpression ) {
312+ return false
313+ }
314+
315+ const callee = parent . callee
316+ if ( callee . type !== AST_NODE_TYPES . MemberExpression ) {
317+ return false
318+ }
319+
320+ try {
321+ const objectTsNode = parserServices . esTreeNodeToTSNodeMap . get ( callee . object )
322+ const objectType = typeChecker . getTypeAtLocation ( objectTsNode )
323+ const typeName = typeChecker . typeToString ( objectType )
324+
325+ // Check if the object is of type Console
326+ return typeName === "Console"
327+ } catch {
328+ return false
329+ }
330+ }
331+
332+ /**
333+ * Checks if a string is an argument to an Error constructor
334+ * using TypeScript type information.
335+ */
336+ function isErrorConstructorArgument (
337+ node : TSESTree . Node ,
338+ typeChecker : ts . TypeChecker ,
339+ parserServices : ReturnType < typeof ESLintUtils . getParserServices >
340+ ) : boolean {
341+ const parent = node . parent
342+ if ( parent ?. type !== AST_NODE_TYPES . NewExpression ) {
343+ return false
344+ }
345+
346+ try {
347+ const calleeTsNode = parserServices . esTreeNodeToTSNodeMap . get ( parent . callee )
348+ const calleeType = typeChecker . getTypeAtLocation ( calleeTsNode )
349+
350+ // Check if the constructor creates an Error type
351+ const constructSignatures = calleeType . getConstructSignatures ( )
352+ for ( const sig of constructSignatures ) {
353+ const returnType = sig . getReturnType ( )
354+ const returnTypeName = typeChecker . typeToString ( returnType )
355+
356+ // Check if it returns Error or any Error subtype
357+ if ( returnTypeName === "Error" || returnTypeName . endsWith ( "Error" ) ) {
358+ return true
359+ }
360+
361+ // Check if the return type extends Error
362+ if ( "getBaseTypes" in returnType && typeof returnType . getBaseTypes === "function" ) {
363+ const baseTypes = returnType . getBaseTypes ( )
364+ if ( baseTypes !== undefined ) {
365+ for ( const baseType of baseTypes ) {
366+ const baseTypeName = typeChecker . typeToString ( baseType )
367+ if ( baseTypeName === "Error" ) {
368+ return true
369+ }
370+ }
371+ }
372+ }
373+ }
374+ } catch {
375+ return false
376+ }
377+
378+ return false
379+ }
380+
300381/**
301382 * Checks if a string is a value for an ignored property/attribute.
302383 */
@@ -636,6 +717,16 @@ export const noUnlocalizedStrings = createRule<[Options], MessageId>({
636717 return
637718 }
638719
720+ // Console method argument (type-aware)
721+ if ( isConsoleMethodArgument ( node , typeChecker , parserServices ) ) {
722+ return
723+ }
724+
725+ // Error constructor argument (type-aware)
726+ if ( isErrorConstructorArgument ( node , typeChecker , parserServices ) ) {
727+ return
728+ }
729+
639730 // Value for ignored property
640731 if ( isIgnoredProperty ( node , options . ignoreProperties ) ) {
641732 return
0 commit comments