Skip to content

bug: Drizzle Type Errors with ESLint/TypeScript-ESLint in create-t3-app ProjectsΒ #2124

@JamesGriz

Description

@JamesGriz

Provide environment information

"ct3aMetadata": {
    "initVersion": "7.39.3"
  },
  System:
    OS: macOS 14.5
    CPU: (11) arm64 Apple M3 Pro
    Memory: 100.58 MB / 18.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.15.0 - ~/.nvm/versions/node/v20.15.0/bin/node
    Yarn: 1.22.22 - ~/.nvm/versions/node/v20.15.0/bin/yarn
    npm: 10.7.0 - ~/.nvm/versions/node/v20.15.0/bin/npm
    pnpm: 10.10.0 - ~/Library/pnpm/pnpm
    Watchman: 2025.04.28.00 - /opt/homebrew/bin/watchman

Describe the bug

While following the modern React tutorial on the t3 introduction page, I ran into some TypeScript setting up my database and fetching posts from drizzle-orm/vercel-postgres. The error appears to come from a compatibility mismatch between "eslint-plugin-drizzle": "^0.2.3" and the newer "eslint": "^9.23.0" version.

Problem Encountered:
With the following db index setup:

// In src/server/db/index
import { drizzle } from "drizzle-orm/vercel-postgres";
import { sql } from "@vercel/postgres";

import * as schema from "./schema";

export const db = drizzle(sql, { schema });

Attempting to fetch the default post data:

// In src/page.tsx
import { db } from "~/server/db";

export default async function HomePage() {
  const posts = await db.query.posts.findMany(); // This line resulted in errors
  // ... rest of the page
}

resulted in ESLint and the IDE reporting errors such as:
Unsafe assignment of an error typed value.
Unsafe call of a(n) error type typed value.
Unsafe member access .findMany on an error typed value.

These messages indicated that TypeScript was unable to correctly infer the type for the posts variable, treating it as an error type while there appeared to be no error for Theo on the tutorial.

Suspected Cause:
Investigation suggested that eslint-plugin-drizzle version 0.2.3 might not be fully compatible with API changes in the newer versions of ESLint v9.x used in the project. This apparent incompatibility could prevent eslint-plugin-drizzle from correctly communicating Drizzle's type information to ESLint and TypeScript, leading to the observed type inference failures.

Resolution:
A solution was found using the @eslint/compat package, which is provided by the ESLint team to help older plugins function with newer ESLint versions. Information on this tool is available in their blog post: Introducing ESLint Compatibility Utilities.
Installing @eslint/compat and modifying eslint.config.js to wrap the Drizzle plugin resolved the errors. The relevant configuration change was:

/ eslint.config.js
// ... other imports
import drizzlePlugin from "eslint-plugin-drizzle"; // Original Drizzle plugin import
import { fixupPluginRules } from "@eslint/compat"; // The magic from @eslint/compat

export default tseslint.config(
  // ... other configs
  {
    files: ["**/*.ts", "**/*.tsx"], // Or your specific files
    plugins: {
      // Wrap the Drizzle plugin here!
      drizzle: fixupPluginRules(drizzlePlugin),
    },
    // ... rest of your Drizzle/ESLint config
  },
  // ...
);

Since it seems like anyone starting a new T3 project with the latest default dependencies might hit this I would like to open a pr fixing the cli template to use this fix.

Reproduction repo

https://github.com/JamesGriz/t3gallery-copy

To reproduce

Clone the example repo, install dependencies with pnpm i and see the error on src/app/page.tsx. Upon replicating the issue myself, I was unsuccessful but decided to post this anyway to confirm if anyone else might have experienced this issue.

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions