porsager / postgres

Postgres.js - The Fastest full featured PostgreSQL client for Node.js, Deno, Bun and CloudFlare
The Unlicense
7.53k stars 275 forks source link

Typing with inserts #958

Open noslouch opened 1 month ago

noslouch commented 1 month ago

Hi there. What a lovely library. I'm encountering a typing issue with dynamic inserts: Type of 'await' operand must either be a valid promise or must not contain a callable 'then' member.

const users = [{
  name: 'Murray',
  age: 68,
  garbage: 'ignore'
},
{
  name: 'Walter',
  age: 80
}];

await sql`insert into users ${sql(users, 'name', 'age')}`; // fine
await sql`insert into users ${sql(users, 'name', 'age')} returning id`; // fine
await sql<{ id: number }[]>`insert into users ${sql(users, 'name', 'age')} returning id`; // Type of 'await' operand must either be a valid promise or must not contain a callable 'then' member.

something I'm doing wrong?

Louis-Tian commented 1 month ago

The following works without a type error as well.

await sql<{ id: number }[]>`insert into users ${sql(users)} returning id`; 

My guess is that it's another case of the inferred typing problem that @porsager is trying to solve in v4.

You can get around this for the time being with an explicit casting.

await sql<{ id: number }[]>`insert into users ${sql(users, 'name', 'age') as any} returning id`; 
noslouch commented 1 month ago

thanks. good suggestion. of course now eslint is complaining about using any, but I can live with that. I'd like to leave this open for posterity, in the hopes a fix lands in 4.

noslouch commented 1 month ago

FWIW never seems to work for me without complaint from ts or eslint.