-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Why is Client.query
s return type not a generic ResultIterator<T>
?
#66
Comments
I think the simple answer is that I don't know how to do that. I remember seeing a project where someone did use types in the way you're suggesting, but I'm not sure how it would work. PostgreSQL basically returns with a list of computed types for any particular query and that's what you'll get. In a more advanced language such as Rust, it would be much more easy I think to specialize the result to a list of expected types and then return a result (okay or error) depending on whether those types matched the actual database response. Not sure if that's possible with TypeScript – but the language keeps growing ... |
The first idea that comes to mind is "brute-casting" the result to the specified type parameter IMO that's good enough though. I can only speak for myself, but the only reason I went for ts-postgres instead of pg as dependency was that I hoped for exactly this. To be at least somewhat aware of the contingency of the runtime types, we could wrap the specified type parameter into a This of course only really works for the primitive types How do you think about this? |
The challenge is that the return type is erased at runtime, unless you use some of the reflection runtime support solutions, see for example https://typescript-rtti.org/. I know that there's an ORM built-in to https://deepkit.io/ as well – perhaps this is more to your liking. Even without the return type capabilities you're asking for, ts-postgres does have a number of features that at least set it apart at the original time of writing, including being written in TypeScript itself! |
I'll check these out, thanks for the pointer. You just linked the README of ts-postgres, where do I have to look? |
@nitwhiz what I meant was the list of features listed right there on the front page – I don't know how things have evolved in the other drivers, but some of those features just weren't there when I set out to write this library. |
For starters, we could return a See also #76. |
Yes that's what I was going for. |
As far as I can tell there are two options:
In both cases, we could consider wrapping |
How about // result: ResultIterator<Readonly<{ message: string; }>>
const result = client.query<{ message: string; }>(
"SELECT 'Hello ' || $1 || '!' AS message",
['world']
);
for await (const row of result) {
// row: Readonly<{ message: string; }>
// 'Hello world!'
console.log(row.message);
} This would be the simplest approach for the user, just as you pointed out. |
@nitwhiz originally, the row being There was another concern as well, but perhaps not a particularly valid one: providing names and values (as arrays), rather than objects should be a more compact representation in memory. The In that case, type Book = [["title", string], ["author", string], ...] Perhaps an interface can be derived from such a type. But it might be possible to provide an overload to const result = await client.query<[string, string, number]>(...); This would work the same, but |
@nitwhiz I have opened a new issue to carry over the second proposal. |
Client.query
returns aResultIterator<Value>
(andClient.query
does not take any type arguments). Is there a specific reason there is no optional type parameter passed down toClient.query
andClient.execute
?How to type the results of
Client.query
?The text was updated successfully, but these errors were encountered: