Skip to content

Type inference limitations #251

@timvandam

Description

@timvandam

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions