Skip to content

Support of SQL template combination typing #193

@nfroidure

Description

@nfroidure

This project is very interesting (I wish I had more time to work on it). I do not use ORM and this approach could help me to reach more robustness.

But for a real world usage, I think we should be able to type all combinations of complex SQL queries since in the real world, we can't have a single query for each db call. We can have things like that:

const with: 'all' | 'organisation' | 'users' = 'all';
const query1 = sql`SELECT * FROM users WHERE id=${1} AND type=${'admin'}`;
const query2 = sql`SELECT * FROM organisations WHERE id=${1} AND type=${'admin'}`;
const query3 = sql`SELECT x.id, x.name, x.kind FROM (
  ${
    with  == 'users' ?
    query1 :
    with  == 'organisations' ?
    query2 :
    sqlFragment`${query2} UNION ${query3}`
  }
) AS x WHERE name LIKE ${'test'}`;

More examples here: https://github.com/nfroidure/pgsqwell/blob/main/src/lib.test.ts

To be type, the above query need the following process to be accomplished:

  • retrieve the AST
  • create as many SQL queries than possible combinations
  • create the type corresponding to them
  • merge those types in a single declaration

It should give something like:

type Rows = ({
  id: Organisation['Id'],
  name: Organisation['Name'],
} | {
  id: User['Id'],
  name: User['Name'],
})[];

Or with (way?) more work:

type Rows<T extends 'all' | 'organisation' | 'users'> =
  T extends 'all'
  ? ({
    id: Organisation['Id'],
    name: Organisation['Name'],
  } | {
    id: User['Id'],
    name: User['Name'],
  })[]
  : T extends 'organisations'
  ? {
    id: Organisation['Id'],
    name: Organisation['Name'],
  }[] 
  : T extends 'users' ? ;
  {
    id: User['Id'],
    name: User['Name'],
  }[] 
  : never

I known the road is long to this point, but I think it would be a real game changer.

What do you think, is it your final goal and if yes, what's the path to this for you ?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions