Skip to content

Instantly share code, notes, and snippets.

@brenapp
Created October 19, 2022 00:26
Show Gist options
  • Save brenapp/0fd798da4a2f2563e5d43c89449c761b to your computer and use it in GitHub Desktop.
Save brenapp/0fd798da4a2f2563e5d43c89449c761b to your computer and use it in GitHub Desktop.
// Utilities
type TrimStart<String extends string> = String extends ` ${infer R}` ? TrimStart<R> : String;
type TrimEnd<String extends string> = String extends `${infer R} ` ? TrimEnd<R> : String;
type Trim<String extends string> = TrimEnd<TrimStart<String>>
type Head<Array extends any[]> = Array[0]
type Tail<Array extends any[]> =
((...a: Array) => void) extends (h: any, ...rest: infer Tail) => void ? Tail : never;
type MergeArrayOfObjects<T extends object[]> = T[1] extends undefined
? Head<T>
: Head<T> & MergeArrayOfObjects<Tail<T>>;
type ParseCreateTableStatement<Text> = Text extends `CREATE ${| "TEMP "
| "TEMPORARY "
| ""}TABLE ${"IF NOT EXISTS" | ""} ${infer SchemaAndName} ${infer Rest}`
? Trim<SchemaAndName> extends `${infer Schema}.${infer Name} ${infer Rest}`
? { schema: Schema; name: Name; rest: Rest }
: { schema: ""; name: SchemaAndName; rest: Rest }
: never;
type ParseCreateTableColumnStatement<Text> =
Text extends `${infer Column},${infer Rest}`
? [
ParseColumnDefinition<Column>,
...ParseCreateTableColumnStatement<Trim<Rest>>
]
: [ParseColumnDefinition<Text>];
type SQLTypes = {
NULL: null;
INTEGER: number;
REAL: number;
TEXT: string;
BLOB: string;
};
type ParseColumnType<Type> = Type extends keyof SQLTypes
? SQLTypes[Type]
: unknown;
type ParseColumnDefinition<Column> =
Column extends `${infer Name} ${infer TypeName}`
? { [V in Name]: ParseColumnType<TypeName> }
: never;
type ParseCreateStatement<
Text extends string,
CreateTableStatement = ParseCreateTableStatement<Text>
> = CreateTableStatement extends never
? never
: {
table: Omit<CreateTableStatement, "rest">;
shape: "rest" extends keyof CreateTableStatement
? CreateTableStatement["rest"] extends `(${infer ColumnStatement})`
? MergeArrayOfObjects<ParseCreateTableColumnStatement<ColumnStatement>>
: never
: never;
};
const QUERY = "CREATE TABLE IF NOT EXISTS BOZO (X NULL, Y INTEGER, Z INTEGER)";
type Bozo = ParseCreateStatement<typeof QUERY>;
type BozoResult = Bozo["shape"];
const a: BozoResult = {
X: null,
Y: 10,
Z: 10
};
console.log(a);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment