ts-safeql / safeql

Validate and auto-generate TypeScript types from raw SQL queries in PostgreSQL.
https://safeql.dev
MIT License
1.34k stars 22 forks source link

"unions must be of the same type" despite being the same time #280

Open timvandam opened 1 week ago

timvandam commented 1 week ago

Describe the bug A clear and concise description of what the bug is.

Getting error ESLint: Invalid Query: Union types must be of the same type (found unknown (524288), unknown (524288), unknown (524288), unknown (524288))(@ts-safeql/ check-sql). These are clearly the same type, in postgres at least. The issue is happening when trying to insert using unnest to a column that takes TEXT.

To keep things short:

(SELECT name, "durationMs"
FROM UNNEST(${name} :: text[], ${timeoutMs} :: int[]) AS t(name, "durationMs"))

Where name has type:

const name: "load-steam-inventory"[] | "load-steam-price"[] | "verify-email-address"[] | "test"[]

If I update this type to:

(
        | 'load-steam-inventory'
        | 'load-steam-price'
        | 'verify-email-address'
        | 'test'
    )[]

It does work. However I don't have control over that as the variable is the output of a function

To Reproduce Steps to reproduce the behavior:

Try inserting many values to a TEXT column using UNNEST with an array with a similar type as mine

Expected behavior A clear and concise description of what you expected to happen.

Should work

Screenshots If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

Additional context Add any other context about the problem here.

May have time to look into this myself this weekend

karlhorky commented 1 week ago

@timvandam If you can provide a reproduction in this format with the table schema, sql tag and ESLint error, that would be helpful to understand the problem:

CREATE TABLE users (
  -- ...
)
// 💥 Query has incorrect type annotation.
//  Expected: { has_private_url: boolean; }
//  Actual: { has_private_url: boolean | null; }[]
await sql<{ has_private_url: boolean }[]>`
  SELECT
    ${true} AS has_private_url
  FROM
    users
`;
timvandam commented 1 week ago

Yea will add some later. Bit swamped with work so just made a quick issue to refine/fix later