drizzle-team / drizzle-orm

Headless TypeScript ORM with a head. Runs on Node, Bun and Deno. Lives on the Edge and yes, it's a JavaScript ORM too 😅
https://orm.drizzle.team
Apache License 2.0
24.52k stars 643 forks source link

[BUG]: delete().returning() type error #1966

Closed ValentinH closed 8 months ago

ValentinH commented 8 months ago

What version of drizzle-orm are you using?

0.29.4

What version of drizzle-kit are you using?

No response

Describe the Bug

I'm trying to return a partial selection of columns when using delete(). From the docs, I should be able to do:

const deletedCarsIdsAndBrands: { id: number, brand: string }[] = await db.delete(cars)
  .where(eq(cars.color, 'green'))
  .returning({ id: cars.id, brand: cars.brand });

However, I get the following type error for the returning argument:

expected 0 arguments, but got 1.

I don't really understand what's wrong because the type definition seems to allow passing an argument: image

Expected behavior

There should be no typescript error and the returned type should be { id: number, brand: string }[]

Environment & setup

No response

ValentinH commented 8 months ago

This error only happens when configuring a hybrid client using neon-http and neon-serverless. See this function that is returning the client:

import { Pool, neon, neonConfig } from '@neondatabase/serverless';
import { drizzle as drizzleNeonHttp } from 'drizzle-orm/neon-http';
import { drizzle as drizzleNeonServerless } from 'drizzle-orm/neon-serverless';

export const initDrizzleClientEdge = ({
  databaseUrl,
  isLocalDev,
}: {
  databaseUrl: string;
  isLocalDev: boolean;
}) => {
  if (isLocalDev) {
    // To have a local neon database like environment
    // see: https://gal.hagever.com/posts/running-vercel-postgres-locally
    // Set the WebSocket proxy to work with the local instance
    neonConfig.wsProxy = (host) => `${host}:5555/v1`;
    // Disable all authentication and encryption
    neonConfig.useSecureWebSocket = false;
    neonConfig.pipelineTLS = false;
    neonConfig.pipelineConnect = false;

    // We need this to connect to the local DB (using a websocket proxy)
    const pool = new Pool({
      connectionString: databaseUrl,
    });

    return drizzleNeonServerless(pool);
  }

  return drizzleNeonHttp(neon(databaseUrl));
};

If I force the return type to be NeonDatabase, the error goes away.

Having NeonDatabase<Record<string, never>> | NeonHttpDatabase<Record<string, never>> creates issues.

Angelelz commented 8 months ago

This is a typescript know limitation. If typescript cannot statically determined which one is being used, it will throw type error when trying to call methods on it. Nothing Drizzle can do. You could try making initDrizzleClientEdge generic over isLocalDev to see if that helps but I don't think it will.

ValentinH commented 8 months ago

Thank you, I'll try this. But it's not super important anyway, I think this can be closed.