What are the Drizzle conventions for giving names to Drizzle return types?

Hello all, I have a question about Drizzle conventions. Do people give names to the return types of their Drizzle calls?
For example, consider the following code:
import { eq } from "drizzle-orm";
import { usersTable } from "../databaseSchema";
import { db } from "../db";

export type User = NonNullable<Awaited<ReturnType<typeof users.get>>>;

export const users = {
  // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
  get: async (username: string) => {
    const rows = await db
      .select({
        id: usersTable.id,
        username: usersTable.username,
        passwordHash: usersTable.passwordHash,
      })
      .from(usersTable)
      .where(eq(usersTable.username, username))
      .limit(1);

    return rows[0];
  },
};

  • Here, we use the ReturnType utility type from TypeScript to satisfy DRY. (If we wanted to violate DRY, we could repeat all the user fields inside of a dedicated User TypeScript interface.)
  • However, we now have a problem where Intellisense does not work properly. In other words, if we mouse over
    user
    in the following code:
    const user = users.get("foo");

    We get the full enumerated object inside of a union with undeifned, instead of the much easier to read and understand User | undefined.
    Does anyone know if there are Drizzle conventions to get smarter Intellisense here?
Was this page helpful?