eslint: no-filter-in-query misses any-typed receivers with parser services
Bug
@convex-dev/no-filter-in-query misses a syntactically recognizable Convex query when parser services are enabled and the database receiver is typed as any.
The same call is reported when type-aware linting is disabled. Enabling type-aware linting therefore removes coverage for this shape.
Minimal reproduction
type Ctx = {
db: any;
};
async function findTodo(ctx: Ctx) {
return await ctx.db
.query("todoItems")
.withIndex("by_file", (q: any) => q.eq("fileId", "file-id"))
.filter((q: any) => q.eq(q.field("status"), "open"))
.first();
}Run ESLint once with the TypeScript parser and the rule, then again with the same config plus parserOptions.projectService: true.
- Without
projectService, the syntax fallback reportsno-filter-in-query. - With
projectService, the rule reports nothing.
Reproduced with:
@convex-dev/eslint-plugin2.0.0- ESLint 9.39.4
- typescript-eslint 8.62.0
- TypeScript 6.0.3
- Convex 1.45.0
- Windows
Cause
In the type-aware path, both isConvexQueryFilterCall() and the receiver-type check return false because the call and receiver are any. hasUsefulReceiverType is also false. However, shouldUseAstFallback starts as !hasTypeInfo, so it remains false whenever parser services exist. The syntax fallback is skipped even though type information was inconclusive.
The relevant flow is:
let shouldUseAstFallback = !hasTypeInfo;
// receiverTypeString === "any"
const hasUsefulReceiverType = false;
// shouldUseAstFallback remains falseThe likely fix is to enable the syntax fallback when the receiver type is any or unknown, while retaining the existing terminal-call guard that prevents array .filter() false positives.
Impact
In one project, a no-cache comparison over the same 23 Convex query filters found 23 reports without type information and 20 with type information. The missing three all used an any database context. Typing that context as Pick<MutationCtx, "db" | "scheduler" | "runMutation"> restored all three reports.
Source: get-convex/convex-backend