safeql: Wrong type on json
Describe the bug
A clear and concise description of what the bug is.
SafeQL doesn’t accept types for json, other than any. Using the json_agg aggregate function makes SafeQL think that the returning column must be any type and throws an error otherwise. The query below throws an incorrect type annotation if any other type is used for the returningJson other than any
type JsonAgg = {
a: string;
b: string;
c: string;
};
type SafeqlRecordWithJson = {
id: number;
firstName: string | null;
lastName: string | null;
returningJson: JsonAgg;
};
export async function getAllTestSafeqlRecordWithJson() {
return await sql<SafeqlRecordWithJson[]>`
SELECT
*,
(
SELECT json_agg(ingredients)::json
FROM (
SELECT
*
FROM
try_safe_ql
)ingredients
) AS returning_json
FROM
test_safeql;
`;
}
To Reproduce Steps to reproduce the behavior:
- Setup SafeQL
- Use the code above in
.tsfile
Expected behavior
A clear and concise description of what you expected to happen.
I expected that using these kinds of aggregate functions shouldn’t cause an error, when i am using the type the query should return or that SafeQL would suggest types other than any
Screenshots If applicable, add screenshots to help explain your problem.



Desktop (please complete the following information):
- OS: MAC OS
- PostgreSQL version 14
- Version [e.g. 22]
Additional context Add any other context about the problem here.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 22
For what it’s worth, I wrote a parser with Peggy. While it’s not a standard, the same syntax is also used by PostGraphile. (Note: that’s tagging in general, not the
@typetag specifically).I think tagging could become a semi-standard if more libraries adopt it so I would be very happy to contribute in that regard. As for types, it’s a bit more difficult because even if we agree that this is Postgres-only, other people might want types for other languages where the syntax would inevitably have to be different.
Thanks for the feedback! you can change that using overrides.types:
It seems like pg comments aren’t parsed at the moment.
About your suggestion - While I understand how it somewhat solves your issue, It doesn’t feel like a future-proof code. Queries are volatile, and comments may get disconnected from the logic. I think gradually adding support for json type inference would be more promising.
There are some shortcomings for sure, but not necessarily intentional. I am happy to expand on it, I’ve only been using it for personal stuff so far. The only criterium I have is that tags should be able to live side by side with a “regular” comment.
Thanks for sharing that @kristiandupont.
It seems like the parser is having hard time catching more complex terms:
But when I think about it, it doesn’t have to. It could return a simple string and then SafeQL could treat it as a “pg” type, which could be transformed to any TypeScript type via
overrides.types:Since SafeQL should be used only with TypeScript & PostgreSQL, I’m less worried about conflicts with other languages. My issue is there can be potentially too much clutter when multiple clients access a single database.
I understand. My only concern here is that there’s no “standard” of defining types in the database comments, which may lead to:
... IS '@type:stringwhile a different tool would use... IS '@type(string)'.I could allow the option to find the type in the comments by regex while using
@type(...)as the default.