#Infer type for SQLite query

1 messages · Page 1 of 1 (latest)

dusty abyss
#
type Query1Params = InferQueryParams<'select * from user where id = $id'>; 
// Result: { $id: string }

type Query2Params = InferQueryParams<'select $name'>; 
// Result: { $name: string }

type Query3Params = InferQueryParams<'insert into users (name, pass) values ($name, $pass)'>; 
// Result: { $name: string, $pass: string }

I need to create an utility type that infer parameters need to passed into a prepared query call (better-sqlite3 and bun:sqlite)

shadow fractal
#

@dusty abyss what do you expect from that type exactly?

#

read the string, extract all words that strat with $, and create an object with those properties?

#

sounds quite complex/overkill

dusty abyss
#

You can see better SQLite 3 api

dusty abyss
shadow fractal
#

what you are trying to do doesn't sound like a query builder, since the user has to provide a complete SQL query

#

also, for 'select * from user where id = $id'
it wouldn't actually return a { $id: string }
not possible to know what the query returns without knowing the column on the table

#

@dusty abyss if you want a type-safe query builder, have a look at Kysely

#

it supports better-sqlite3 (as well as some other DB drivers)

#

and you can even use it as query builder in other runtimes (Deno, Bun, browser) (only as a query builder, not as a query runner)

dusty abyss
#

And also learn some more typescript

#

Don’t tell me to use other libraries

dusty abyss
#

I just want a really small query builder

#

I published sql-light

dusty abyss
#
    /**
     * Input value type
     */
    export type ParamsValue = string | number | null | Buffer;

    type EndToken = ',' | ' ' | ';' | ')';

    type Analyze<T extends string, Current extends string = ''> = T extends `${infer Char}${infer Rest}`
        ? CharCheck<Char, Current, Rest>
        : T extends EndToken ? {} : PropObject<`${Current}${T}`>;

    type CharCheck<Char extends string, Current extends string, Rest extends string = ''> = Char extends EndToken
        ? PropObject<Current> & QueryInfer<Rest>
        : Analyze<Rest, `${Current}${Char}`>

    type PropObject<Name extends string> = { [K in `$${Name}`]: ParamsValue };

    type SliceEnd<T extends string, Token extends string> = T extends `${string}${Token}${infer Rest}` ? Rest : ''

    /**
     * Infer from a query string
     */
    export type QueryInfer<T extends string> =
        // Escape string
        T extends `${infer X}'${infer Y}`
        ? QueryInfer<X> & QueryInfer<SliceEnd<Y, `'`>>

        : T extends `${infer X}"${infer Y}`
        ? QueryInfer<X> & QueryInfer<SliceEnd<Y, `"`>>

        // Check token stuff
        : T extends `${string}$${infer Rest}`
        ? Analyze<Rest> : {};

Can anyone find a better solution than this