Skip to content

Commit

Permalink
Fix some undefined types issues (#447)
Browse files Browse the repository at this point in the history
* Support `exactOptionalPropertyTypes` - fixes #407

* Allow `undefined` properties with insert helper (types only) - fixes #446

* Allow sql fragements as tagged template parameters (types only)
  • Loading branch information
Minigugus committed Aug 9, 2022
1 parent 3415278 commit 097d272
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 57 deletions.
122 changes: 66 additions & 56 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Readable, Writable } from 'node:stream'
* @param options Connection options - default to the same as psql
* @returns An utility function to make queries to the server
*/
declare function postgres<T extends PostgresTypeList>(options?: postgres.Options<T>): postgres.Sql<PostgresTypeList extends T ? {} : { [type in keyof T]: T[type] extends {
declare function postgres<T extends PostgresTypeList>(options?: postgres.Options<T> | undefined): postgres.Sql<PostgresTypeList extends T ? {} : { [type in keyof T]: T[type] extends {
serialize: (value: infer R) => any,
parse: (raw: any) => infer R
} ? R : never }>
Expand All @@ -15,7 +15,7 @@ declare function postgres<T extends PostgresTypeList>(options?: postgres.Options
* @param options Connection options - default to the same as psql
* @returns An utility function to make queries to the server
*/
declare function postgres<T extends PostgresTypeList>(url: string, options?: postgres.Options<T>): postgres.Sql<PostgresTypeList extends T ? {} : { [type in keyof T]: T[type] extends {
declare function postgres<T extends PostgresTypeList>(url: string, options?: postgres.Options<T> | undefined): postgres.Sql<PostgresTypeList extends T ? {} : { [type in keyof T]: T[type] extends {
serialize: (value: infer R) => any,
parse: (raw: any) => infer R
} ? R : never }>
Expand All @@ -25,9 +25,9 @@ declare function postgres<T extends PostgresTypeList>(url: string, options?: pos
*/
interface BaseOptions<T extends PostgresTypeList> {
/** Postgres ip address[s] or domain name[s] */
host: string | string[];
host: string | string[] | undefined;
/** Postgres server[s] port[s] */
port: number | number[];
port: number | number[] | undefined;
/** unix socket path (usually '/tmp') */
path: string | undefined;
/**
Expand Down Expand Up @@ -84,24 +84,24 @@ interface BaseOptions<T extends PostgresTypeList> {
/** Transforms incoming and outgoing column names */
column?: ((column: string) => string) | {
/** SQL to JS */
from?: (column: string) => string;
from?: ((column: string) => string) | undefined;
/** JS to SQL */
to?: (column: string) => string;
};
to?: ((column: string) => string) | undefined;
} | undefined;
/** Transforms incoming and outgoing row values */
value?: ((value: any) => any) | {
/** SQL to JS */
from?: (value: unknown) => any;
from?: ((value: unknown) => any) | undefined;
// /** JS to SQL */
// to?: (value: unknown) => any; // unused
};
// to?: ((value: unknown) => any) | undefined; // unused
} | undefined;
/** Transforms entire rows */
row?: ((row: postgres.Row) => any) | {
/** SQL to JS */
from?: (row: postgres.Row) => any;
from?: ((row: postgres.Row) => any) | undefined;
// /** JS to SQL */
// to?: (row: postgres.Row) => any; // unused
};
// to?: ((row: postgres.Row) => any) | undefined; // unused
} | undefined;
};
/** Connection parameters */
connection: Partial<postgres.ConnectionParameters>;
Expand Down Expand Up @@ -164,7 +164,7 @@ type Keys = string

type SerializableObject<T, K extends readonly any[], TT> =
number extends K['length'] ? {} :
(Record<Keys & (keyof T) & (K['length'] extends 0 ? string : K[number]), postgres.SerializableParameter<TT> | postgres.JSONValue> & Record<string, any>)
Partial<(Record<Keys & (keyof T) & (K['length'] extends 0 ? string : K[number]), postgres.ParameterOrJSON<TT> | undefined> & Record<string, any>)>

type First<T, K extends readonly any[], TT> =
// Tagged template string call
Expand Down Expand Up @@ -209,17 +209,17 @@ declare namespace postgres {
line: string;
routine: string;

detail?: string;
hint?: string;
internal_position?: string;
internal_query?: string;
where?: string;
schema_name?: string;
table_name?: string;
column_name?: string;
data?: string;
type_name?: string;
constraint_name?: string;
detail?: string | undefined;
hint?: string | undefined;
internal_position?: string | undefined;
internal_query?: string | undefined;
where?: string | undefined;
schema_name?: string | undefined;
table_name?: string | undefined;
column_name?: string | undefined;
data?: string | undefined;
type_name?: string | undefined;
constraint_name?: string | undefined;

/** Only set when debug is enabled */
query: string;
Expand Down Expand Up @@ -285,34 +285,34 @@ declare namespace postgres {

interface Options<T extends PostgresTypeList> extends Partial<BaseOptions<T>> {
/** @inheritdoc */
host?: string;
host?: string | undefined;
/** @inheritdoc */
port?: number;
port?: number | undefined;
/** @inheritdoc */
path?: string;
path?: string | undefined;
/** Password of database user (an alias for `password`) */
pass?: Options<T>['password'];
pass?: Options<T>['password'] | undefined;
/**
* Password of database user
* @default process.env['PGPASSWORD']
*/
password?: string | (() => string | Promise<string>);
password?: string | (() => string | Promise<string>) | undefined;
/** Name of database to connect to (an alias for `database`) */
db?: Options<T>['database'];
db?: Options<T>['database'] | undefined;
/** Username of database user (an alias for `user`) */
username?: Options<T>['user'];
username?: Options<T>['user'] | undefined;
/** Postgres ip address or domain name (an alias for `host`) */
hostname?: Options<T>['host'];
hostname?: Options<T>['host'] | undefined;
/**
* Disable prepared mode
* @deprecated use "prepare" option instead
*/
no_prepare?: boolean;
no_prepare?: boolean | undefined;
/**
* Idle connection timeout in seconds
* @deprecated use "idle_timeout" option instead
*/
timeout?: Options<T>['idle_timeout'];
timeout?: Options<T>['idle_timeout'] | undefined;
}

interface ParsedOptions<T extends JSToPostgresTypeMap> extends BaseOptions<{ [name in keyof T]: PostgresType<T[name]> }> {
Expand Down Expand Up @@ -380,7 +380,7 @@ declare namespace postgres {
| 'CONNECTION_ENDED';
errno: this['code'];
address: string;
port?: number;
port?: number | undefined;
}

interface NotSupportedError extends globalThis.Error {
Expand Down Expand Up @@ -437,21 +437,21 @@ declare namespace postgres {

interface LargeObject {
writable(options?: {
highWaterMark?: number,
start?: number
}): Promise<Writable>;
highWaterMark?: number | undefined,
start?: number | undefined
} | undefined): Promise<Writable>;
readable(options?: {
highWaterMark?: number,
start?: number,
end?: number
}): Promise<Readable>;
highWaterMark?: number | undefined,
start?: number | undefined,
end?: number | undefined
} | undefined): Promise<Readable>;

close(): Promise<void>;
tell(): Promise<void>;
read(size: number): Promise<void>;
write(buffer: Uint8Array): Promise<[{ data: Uint8Array }]>;
truncate(size: number): Promise<void>;
seek(offset: number, whence?: number): Promise<void>;
seek(offset: number, whence?: number | undefined): Promise<void>;
size(): Promise<[{ position: bigint, size: bigint }]>;
}

Expand Down Expand Up @@ -499,7 +499,7 @@ declare namespace postgres {
type: number;
table: number;
number: number;
parser?(raw: string): unknown;
parser?: ((raw: string) => unknown) | undefined;
}

type ColumnList<T> = (T extends string ? Column<T> : never)[];
Expand Down Expand Up @@ -550,7 +550,7 @@ declare namespace postgres {
stream(cb: (row: NonNullable<TRow[number]>, result: ExecutionResult<TRow[number]>) => void): never;
forEach(cb: (row: NonNullable<TRow[number]>, result: ExecutionResult<TRow[number]>) => void): Promise<ExecutionResult<TRow[number]>>;

cursor(rows?: number): AsyncIterable<NonNullable<TRow[number]>[]>;
cursor(rows?: number | undefined): AsyncIterable<NonNullable<TRow[number]>[]>;
cursor(cb: (row: [NonNullable<TRow[number]>]) => void): Promise<ExecutionResult<TRow[number]>>;
cursor(rows: number, cb: (rows: NonNullable<TRow[number]>[]) => void): Promise<ExecutionResult<TRow[number]>>;
}
Expand Down Expand Up @@ -583,6 +583,16 @@ declare namespace postgres {
rest: U;
}

type Fragment = PendingQuery<any>

type ParameterOrJSON<T> =
| SerializableParameter<T>
| JSONValue

type ParameterOrFragment<T> =
| SerializableParameter<T>
| Fragment

interface Sql<TTypes extends JSToPostgresTypeMap> {
/**
* Query helper
Expand All @@ -598,7 +608,7 @@ declare namespace postgres {
* @param parameters Interpoled values of the template string
* @returns A promise resolving to the result of your query
*/
<T extends readonly (object | undefined)[] = Row[]>(template: TemplateStringsArray, ...parameters: readonly (SerializableParameter<TTypes[keyof TTypes]> | PendingQuery<any>)[]): PendingQuery<T>;
<T extends readonly (object | undefined)[] = Row[]>(template: TemplateStringsArray, ...parameters: readonly (ParameterOrFragment<TTypes[keyof TTypes]>)[]): PendingQuery<T>;

CLOSE: {};
END: this['CLOSE'];
Expand All @@ -611,22 +621,22 @@ declare namespace postgres {
[name in keyof TTypes]: (value: TTypes[name]) => postgres.Parameter<TTypes[name]>
};

unsafe<T extends any[] = (Row & Iterable<Row>)[]>(query: string, parameters?: SerializableParameter<TTypes[keyof TTypes]>[], queryOptions?: UnsafeQueryOptions): PendingQuery<T>;
end(options?: { timeout?: number }): Promise<void>;
unsafe<T extends any[] = (Row & Iterable<Row>)[]>(query: string, parameters?: (ParameterOrJSON<TTypes[keyof TTypes]>)[] | undefined, queryOptions?: UnsafeQueryOptions | undefined): PendingQuery<T>;
end(options?: { timeout?: number | undefined } | undefined): Promise<void>;

listen(channel: string, onnotify: (value: string) => void, onlisten?: () => void): ListenRequest;
listen(channel: string, onnotify: (value: string) => void, onlisten?: (() => void) | undefined): ListenRequest;
notify(channel: string, payload: string): PendingRequest;

subscribe(event: string, cb: (row: Row | null, info: ReplicationEvent) => void, onsubscribe?: () => void): Promise<SubscriptionHandle>;
subscribe(event: string, cb: (row: Row | null, info: ReplicationEvent) => void, onsubscribe?: (() => void) | undefined): Promise<SubscriptionHandle>;

largeObject(oid?: number, /** @default 0x00020000 | 0x00040000 */ mode?: number): Promise<LargeObject>;
largeObject(oid?: number | undefined, /** @default 0x00020000 | 0x00040000 */ mode?: number | undefined): Promise<LargeObject>;

begin<T>(cb: (sql: TransactionSql<TTypes>) => T | Promise<T>): Promise<UnwrapPromiseArray<T>>;
begin<T>(options: string, cb: (sql: TransactionSql<TTypes>) => T | Promise<T>): Promise<UnwrapPromiseArray<T>>;

array<T extends SerializableParameter<TTypes[keyof TTypes]>[] = SerializableParameter<TTypes[keyof TTypes]>[]>(value: T, type?: number): ArrayParameter<T>;
file<T extends readonly any[] = Row[]>(path: string | Buffer | URL | number, options?: { cache?: boolean }): PendingQuery<T>;
file<T extends readonly any[] = Row[]>(path: string | Buffer | URL | number, args: SerializableParameter<TTypes[keyof TTypes]>[], options?: { cache?: boolean }): PendingQuery<T>;
array<T extends SerializableParameter<TTypes[keyof TTypes]>[] = SerializableParameter<TTypes[keyof TTypes]>[]>(value: T, type?: number | undefined): ArrayParameter<T>;
file<T extends readonly any[] = Row[]>(path: string | Buffer | URL | number, options?: { cache?: boolean | undefined } | undefined): PendingQuery<T>;
file<T extends readonly any[] = Row[]>(path: string | Buffer | URL | number, args: (ParameterOrJSON<TTypes[keyof TTypes]>)[], options?: { cache?: boolean | undefined } | undefined): PendingQuery<T>;
json(value: JSONValue): Parameter;
}

Expand All @@ -635,7 +645,7 @@ declare namespace postgres {
* When executes query as prepared statement.
* @default false
*/
prepare?: boolean;
prepare?: boolean | undefined;
}

interface TransactionSql<TTypes extends JSToPostgresTypeMap> extends Sql<TTypes> {
Expand Down
3 changes: 2 additions & 1 deletion types/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
],
"esModuleInterop": true,
"strict": true,
"noImplicitAny": true
"noImplicitAny": true,
"exactOptionalPropertyTypes": true
}
}

0 comments on commit 097d272

Please sign in to comment.