Skip to content

Commit 84f71ce

Browse files
committed
refactor: use ts.TypeFlags instead of magic numbers
- Import typescript at runtime (not just as type) to access TypeFlags enum - More readable and maintainable than numeric literals
1 parent 02acd46 commit 84f71ce

File tree

1 file changed

+21
-17
lines changed

1 file changed

+21
-17
lines changed

src/rules/no-unlocalized-strings.ts

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { AST_NODE_TYPES, ESLintUtils, type TSESTree } from "@typescript-eslint/utils"
2-
import type ts from "typescript"
2+
import ts from "typescript"
33

44
import { createRule } from "../utils/create-rule.js"
55

@@ -594,17 +594,21 @@ function functionReturnsString(
594594
): boolean {
595595
try {
596596
const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node)
597-
const signature = typeChecker.getSignatureFromDeclaration(tsNode as ts.SignatureDeclaration)
598597

599-
if (signature === undefined) {
600-
// No signature info - allow by name to avoid false positives
598+
// Get the type of the function itself
599+
const functionType = typeChecker.getTypeAtLocation(tsNode)
600+
const callSignatures = functionType.getCallSignatures()
601+
602+
if (callSignatures.length === 0) {
603+
// No call signatures - allow by name to avoid false positives
601604
return true
602605
}
603606

604-
const returnType = typeChecker.getReturnTypeOfSignature(signature)
605-
606-
// Check if it's a string type or union containing string
607-
return isStringishType(returnType, typeChecker)
607+
// Check all call signatures - all must return string-ish
608+
return callSignatures.every((signature) => {
609+
const returnType = typeChecker.getReturnTypeOfSignature(signature)
610+
return isStringishType(returnType, typeChecker)
611+
})
608612
} catch {
609613
// Type checking can fail - allow by name to avoid false positives
610614
return true
@@ -614,33 +618,33 @@ function functionReturnsString(
614618
/**
615619
* Checks if a type is string-ish: string, string literal, or union of these with null/undefined.
616620
*/
617-
function isStringishType(type: ts.Type, typeChecker: ts.TypeChecker): boolean {
621+
function isStringishType(type: ts.Type, _typeChecker: ts.TypeChecker): boolean {
622+
const flags = type.getFlags()
623+
618624
// Check if it's a union type
619625
if (type.isUnion()) {
620626
// All non-null/undefined members must be string-ish
621627
const nonNullableTypes = type.types.filter((t) => {
622-
const flags = t.getFlags()
628+
const f = t.getFlags()
623629
// Skip null and undefined
624-
return !(flags & 32768) && !(flags & 65536) // Null = 32768, Undefined = 65536
630+
return (f & ts.TypeFlags.Null) === 0 && (f & ts.TypeFlags.Undefined) === 0
625631
})
626632

627633
// If only null/undefined, that's not a string return
628634
if (nonNullableTypes.length === 0) {
629635
return false
630636
}
631637

632-
return nonNullableTypes.every((t) => isStringishType(t, typeChecker))
638+
return nonNullableTypes.every((t) => isStringishType(t, _typeChecker))
633639
}
634640

635-
const flags = type.getFlags()
636-
637-
// String type (4) or string literal (128)
638-
if ((flags & 4) !== 0 || (flags & 128) !== 0) {
641+
// String type or string literal
642+
if ((flags & ts.TypeFlags.String) !== 0 || (flags & ts.TypeFlags.StringLiteral) !== 0) {
639643
return true
640644
}
641645

642646
// Template literal type
643-
if ((flags & 134217728) !== 0) {
647+
if ((flags & ts.TypeFlags.TemplateLiteral) !== 0) {
644648
return true
645649
}
646650

0 commit comments

Comments
 (0)