Skip to content

Regression: ExecuteValues no longer allows Record type #4275

@uPaymeiFixit

Description

@uPaymeiFixit

Initially the type was any, then #3985 disallowed a few primitive types, then #4133 tightened the array branch of ExecuteValues from ({} | null)[] to ExecuteValues[]. This forces nested objects to resolve through the recursive object branch { [key: string]: ExecuteValues }, which rejects Record<string, unknown> at the type level even though it works at runtime. It looks like QueryValues probably has a similar issue, but when passing a Record in at the top level instead of inside an array.

Passing in Records is a pretty common thing to do, either from untyped input, ORMs, or just structuring the data as JSON and typing it as a Record (what our company is doing), so I'd have to imagine this is having an impact on at least a few others.

const value: Record<string, unknown> = { hello: 'world' };
conn.execute('INSERT INTO data (json_col) VALUES (?)', [value]);
// Type 'Record<string | number | symbol, unknown>' is not assignable to type 'ExecuteValues'.

This might be a good compromise. There are certainly edge cases where mistakes can be made, but for the most part I think it sits nicely between any and being too strict / overly prescriptive.

 export type ExecuteValues =
   | string
   | number
   | bigint
   | boolean
   | Date
   | null
   | Blob
   | Buffer
   | Uint8Array
   | ExecuteValues[]
-  | { [key: string]: ExecuteValues };
+  | { [key: string]: unknown };

 export type QueryValues =
   | string
   | number
   | bigint
   | boolean
   | Date
   | null
   | undefined
   | Blob
   | Buffer
   | Uint8Array
   | Raw
   | ({} | null | undefined)[]
-  | { [key: string]: QueryValues };
+  | { [key: string]: unknown };

export type ExecuteValues =
| string
| number
| bigint
| boolean
| Date
| null
| Blob
| Buffer
| Uint8Array
| ExecuteValues[]
| { [key: string]: ExecuteValues };
export type QueryValues =
| string
| number
| bigint
| boolean
| Date
| null
| undefined
| Blob
| Buffer
| Uint8Array
| Raw
| ({} | null | undefined)[]
| { [key: string]: QueryValues };

In case it helps, I edited my original tsplayground to add Records.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions