safeql
safeql copied to clipboard
Type inference limitations
Describe the bug A clear and concise description of what the bug is.
Not sure if a bug or limitation, but types are not inferred accurately.
I have two ways of providing a number[]
to UNNEST
, but one of them forces me to cast to int[]
while the other does not
To Reproduce Steps to reproduce the behavior:
Example setup:
export async function upsertWorkOrderItems(
items: {
workOrderId: number;
uuid: string;
shopifyOrderLineItemId: ID | null;
data: WorkOrderItemData;
}[],
) {
if (!isNonEmptyArray(items)) {
return;
}
const { shopifyOrderLineItemId, workOrderId, uuid, data } = nest(items);
await sql`
INSERT INTO "WorkOrderItem" ("workOrderId", uuid, "shopifyOrderLineItemId", data)
SELECT *
FROM UNNEST(${workOrderId} :: int[],
${uuid} :: uuid[],
${shopifyOrderLineItemId} :: text[],
${data.map(data => JSON.stringify(data))} :: jsonb[]);`;
}
export type Nest<T extends object> = { [K in keyof T]: T[K][] };
/**
* The opposite of postgres' UNNEST.
* Takes an array of objects and returns an array of properties.
*/
export function nest<T extends object>(items: NonEmptyArray<T>): Nest<T> {
const [item] = items;
const keys = Object.keys(item) as (keyof T)[];
return Object.fromEntries(keys.map(key => [key, items.map(item => item[key])])) as Nest<T>;
}
Expected behavior A clear and concise description of what you expected to happen.
I would expect to not be forced to provide type hints like :: int[]
. If I remove this cast I get errors. (ESLint: Invalid Query: function pg_catalog.unnest(text) does not exist(@ts-safeql/check-sql)
)
However, if I replace ${workOrderId}
with ${items.map(item => item.workOrderId)}
I am able to omit the :: int[]. The types of both is number[]
, so I would not expect this
Screenshots If applicable, add screenshots to help explain your problem.
N/A
Desktop (please complete the following information):
- OS: [e.g. iOS] macos
- PostgreSQL version [e.g. 13, 14] 15
- Version [e.g. 22] latest
Additional context Add any other context about the problem here.