목표

주의사항

Type

type Trim<T extends string, Acc extends string = '', Separator extends string = ' '> 
    = T extends `${infer Char}${infer Rest}`
        ? (Char extends Separator
            ? Trim<Rest, Acc>
            : Trim<Rest, `${Acc}${Char}`>)
        : (T extends ''
            ? Acc
            : never);

type TrimComments<T extends string> = 
      T extends `${infer Head}#${any}\\n${infer Tail}`
        ? TrimComments<`${Head}\\n${Tail}`> 
    : T extends `${infer Head}--${any}\\n${infer Tail}`
        ? TrimComments<`${Head}\\n${Tail}`>
    : T extends `${infer Head}/*${any}*/${infer Tail}`
        ? TrimComments<`${Head}${Tail}`>
    // : T extends `${infer Head}#${any}\\r\\n${infer Tail}`
    //     ? TrimComments<`${Head}\\r\\n${Tail}`>
    // : T extends `${infer Head}--${any}\\r\\n${infer Tail}`
    //     ? TrimComments<`${Head}\\r\\n${Tail}`>
    : T;

type ParseQueryBegin<T extends string>
    = T extends `${string}{${infer I}}${infer Tail extends string}` ? 
        { i: I, tail: Tail } : 
        never;

type ParseQueryRecur<T extends { i: string, tail: string }>
    = T['tail'] extends `${string}{${infer I}}${infer TailNext extends string}` ? 
        ParseQueryRecur<{ i: T['i'] | I, tail: TailNext }> :
        T['i'];

type ParseQueryToInputUnion<T extends string> = ParseQueryRecur<ParseQueryBegin<T>>;

export type ExtractFromQuery<T extends string> 
    = Record<
        ParseQueryToInputUnion<
            Trim<
                TrimComments<T>
            >
        >, 
        any
    >;

Examples

/*{
    id: any;
    pw: any;
    nick: any;
}*/
type ExampleA = ExtractFromQuery<"SELECT FROM {i d} AND {pw} AND {nick} GG {id}">;

/*{
    id: any;
    pw: any;
    nick: any;
    createDate: any;
}*/
type ExampleB = ExtractFromQuery<`
    SELECT abc, def
    FROM table                /* {블록코멘트} */
    WHERE id = {id} AND       -- {라인코멘트1}
          pw = {pw} AND       #  {라인코멘트2}
          nick = {nick} AND
          create_date = {createDate} AND
          parent_id = {id}                # 중복 컬럼: {id}
`>;

function RunQuery<TQry extends string>(query: TQry, input: ExtractFromQuery<TQry>) {}
RunQuery('SELECT * FROM table WHERE id={id} AND name={name}', { id: 'a', name: 123 })