From 3c4e90aba36e188aab9873aad5cc2c206d37dfa4 Mon Sep 17 00:00:00 2001 From: Minigugus <43109623+Minigugus@users.noreply.github.com> Date: Sat, 2 Apr 2022 11:22:15 +0200 Subject: [PATCH] Fix sql function overload type inference (#294) fixes #283 --- types/index.d.ts | 84 ++++++++++++++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 31 deletions(-) diff --git a/types/index.d.ts b/types/index.d.ts index 1cd78b19..d4ff3d17 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -151,6 +151,44 @@ type UnwrapPromiseArray = T extends any[] ? { [k in keyof T]: T[k] extends Promise ? R : T[k] } : T; +type Keys = string + +type SerializableObject = + number extends K['length'] ? {} : + Record + +type First = + // Tagged template string call + T extends TemplateStringsArray ? TemplateStringsArray : + // Identifiers helper + T extends string ? string : + // Dynamic values helper (depth 2) + T extends readonly any[][] ? postgres.EscapableArray[] : + // Insert/update helper (depth 2) + T extends (object & infer R)[] ? SerializableObject[] : + // Dynamic values helper (depth 1) + T extends readonly any[] ? postgres.EscapableArray : + // Insert/update helper (depth 1) + T extends object ? SerializableObject : + // Unexpected type + never + +type Rest = + T extends TemplateStringsArray ? never : // force fallback to the tagged template function overload + T extends string ? string[] : + T extends readonly any[][] ? [] : + T extends (object & infer R)[] ? (Keys & keyof R)[] : + T extends readonly any[] ? [] : + T extends object ? (Keys & keyof T)[] : + any + +type Return = + [T] extends [TemplateStringsArray] ? + [unknown] extends [T] ? postgres.Helper : // ensure no `PendingQuery` with `any` types + [TemplateStringsArray] extends [T] ? postgres.PendingQuery : + postgres.Helper : + postgres.Helper + declare namespace postgres { class PostgresError extends Error { name: 'PostgresError'; @@ -408,30 +446,23 @@ declare namespace postgres { size(): Promise<[{ position: bigint, size: bigint }]>; } - type Serializable = null + type EscapableArray = (string | number)[] + + type Serializable = never + | null | boolean | number | string | Date | Uint8Array; - type SerializableParameter = Serializable + type SerializableParameter = never + | Serializable | Helper | Parameter | ArrayParameter - | Record // implicit JSON | readonly SerializableParameter[]; - type HelperSerializable = { [index: string]: SerializableParameter } | { [index: string]: SerializableParameter }[]; - - type SerializableKeys = (keyof T) extends infer R - ? R extends keyof T - ? T[R] extends SerializableParameter - ? R - : never - : keyof T - : keyof T; - interface Row { [column: string]: any; } @@ -526,30 +557,21 @@ declare namespace postgres { } interface Sql { + /** + * Query helper + * @param first Define how the helper behave + * @param rest Other optional arguments, depending on the helper type + * @returns An helper object usable as tagged template parameter in sql queries + */ + >(first: T & First, ...rest: K): Return; /** * Execute the SQL query passed as a template string. Can only be used as template string tag. * @param template The template generated from the template string - * @param args Interpoled values of the template string + * @param parameters Interpoled values of the template string * @returns A promise resolving to the result of your query */ - (template: TemplateStringsArray, ...args: SerializableParameter[]): PendingQuery>; - - /** - * Escape column names - * @param columns Columns to escape - * @returns A formated representation of the column names - */ - (columns: string[]): Helper; - (...columns: string[]): Helper; - - /** - * Extract properties from an object or from an array of objects - * @param objOrArray An object or an array of objects to extract properties from - * @param keys Keys to extract from the object or from objets inside the array - * @returns A formated representation of the parameter - */ - >(objOrArray: T, ...keys: U[]): Helper; + (template: TemplateStringsArray, ...parameters: (SerializableParameter | PendingQuery)[]): PendingQuery>; CLOSE: {}; END: this['CLOSE'];