Skip to content

Support of SQL template combination typing #193

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 ?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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