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.
Initially the type was
any, then #3985 disallowed a few primitive types, then #4133 tightened the array branch ofExecuteValuesfrom({} | null)[]toExecuteValues[]. This forces nested objects to resolve through the recursive object branch{ [key: string]: ExecuteValues }, which rejectsRecord<string, unknown>at the type level even though it works at runtime. It looks likeQueryValuesprobably 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.
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
anyand being too strict / overly prescriptive.node-mysql2/typings/mysql/lib/protocol/sequences/Query.d.ts
Lines 7 to 33 in 77afd80
In case it helps, I edited my original tsplayground to add Records.