ts-safeql / safeql

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

Type widening array elements #234

Open timvandam opened 1 month ago

timvandam commented 1 month ago

Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Currently I am not able to pass a ('literal1' | 'literal2')[] to a VARCHAR(255)[] column. Widening the type would fix this. This should not happen when using some enum array as column type, I think it only makes sense for VARCHAR/TEXT/number columns.

As an example:

await sql`
    INSERT INTO users (public_id, username, roles)
    VALUES (${nanoid()}, ${username}, ${[defaultRole]});`;
//                                      ^
// Invalid Query: The type "("superuser" | "new_user")[]" has no corresponding PostgreSQL type.

Describe the solution you'd like A clear and concise description of what you want to happen.

Automatically widen types depending on the postgres column

Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.

I can cast to a string[] myself with as string[], but this is error prone

Additional context Add any other context or screenshots about the feature request here.

timvandam commented 1 month ago

I've noticed that this does work with VARCHAR(255) rather than VARCHAR(255)[]

timvandam commented 1 month ago

I did some debugging and it seems like it only fails when you do not use a TS identifier. This code should make it work: https://github.com/ts-safeql/safeql/blob/9c8ead2523370bdfdcadd3dabbfe1231cb764ddd/packages/eslint-plugin/src/utils/ts-pg.utils.ts#L148-L154, but it only runs when on identifiers while I am using an array literal

I am not sure how to fix this since I am not too familiar with the TS compiler api, but it seems like an additional check is needed near the code linked above. Additionally https://github.com/ts-safeql/safeql/blob/9c8ead2523370bdfdcadd3dabbfe1231cb764ddd/packages/eslint-plugin/src/utils/ts.utils.ts#L13-L31 would need to support non references but also literals

Newbie012 commented 1 month ago

Thanks, I'll look into it