Skip to content

Instantly share code, notes, and snippets.

@roger-hamilton
Last active August 11, 2021 13:49
Show Gist options
  • Save roger-hamilton/566b2988f61e055ad2fc6a4db7cacbba to your computer and use it in GitHub Desktop.
Save roger-hamilton/566b2988f61e055ad2fc6a4db7cacbba to your computer and use it in GitHub Desktop.
Sql Command parameter extraction
type WhiteSpace = ' ' | '\t' | '\n' | '\r' | '\f'
type Trim<S extends string> =
S extends `${WhiteSpace}${infer T}` ? Trim<T>
: S extends `${infer T}${WhiteSpace}` ? Trim<T>
: S
type SqlParamsUnion<T extends string, P extends string = '@'> =
T extends `${any}${P}${infer P}${WhiteSpace}${infer R}`
? Trim<P> | SqlParamsUnion<R>
: never;
type DbType = string | number | boolean | Date | null;
export type ParamType<T extends DbType = DbType> = T | { dbType: any, value: T }
export type SqlParamsObject<T extends string, P extends string = '@'> = {
[K in SqlParamsUnion<T, P>]: ParamType
};
import { SqlParamsObject } from './SqlParams.ts';
// this will enforce that each sql param for the command is passed in if listed in the command
// and if the type of the sql string is known at the callsite)
export const execSql = async <T extends string>(sql: T, params: SqlParamsObject<T>) => {
//...do stuff
}
const sql = `
select
*
from bbb
where bbb.id = @id
and type = @hello
`;
// This passes type checking:
execSql(sql, {
hello: 'world',
id: 10,
});
// These do not
execSql(sql, {
hello: 'world',
}); // Property 'id' is missing in type '{ hello: string; }'
execSql(sql, {
hello: 'world',
id: 10
something: 'else',
}); // Object literal may only specify known properties, and 'something' does not exist in type
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment