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
Question: Why are query results marked as readonly
?
#218
Comments
I did the switch, and the reason the For your example - do you have to have all the type defs? The following should work: async function getResponses() {
return this.db.pool.many<UserAssessmentResponse>(sql`
SELECT *
FROM user_assessment_response
WHERE user_assessment_id = ${userAssessmentId};
`);
} Alternatively, if your project requires explicit typedefs, you could just add |
Thanks, @mmkal I could do as you suggested, but in other places that I use the returned |
I cannot think of a single valid use case where one would want / should mutate object or an array. Everything in your codebase that is either a parameter or a return value should be read only. Otherwise, you are effectively creating side-effects and hard to debug issue. However, I am still only beginning to adopt TS and perhaps I am closing this as there is no action for now, but please continue the conversation. |
@gajus I agree, it's very rare to have a valid use case for mutating arrays anywhere. The only reason I'd advocate for dropping the readonly keyword is that it's not really slonik's job to force library users not to shoot themselves in the foot. Or to jump through hoops like forcing them to add readonly to their own typedefs, or the There are interop problems too. Not all libraries use |
This is a great discussion, thank you both. While I'm no TypeScript expert, my understanding is that the I also tend to agree with @mmkal about the library not dictating how our return values can be used, especially since at the end of the day it's just a javascript array with no special protections (other than the type system). Another alternative that would make more sense to me from a TypesScritpt standpoint is to use something like the built-in Here's another resource I found useful: And here's a counter argument for using the In summary, I just found the readonly modifier to be unexpected, particularly since I had existing code using the previous major version (i.e. before the documented breaking change). If I had come into the library fresh, not having upgraded versions, I don't know if I would have thought twice about it. Thanks for a great library and a thoughtful discussion! |
There is a large difference between making parameters read only and making return values read only. Read only parameters tell the user that the function will not mutate the parameters but will accept both mutable and immutable values. Read only return values prevent the user from mutating the value and passing it to other functions (some maybe in third party libraries) that don't have their parameters marked read only. Updating to version 23 in our project would require changing types across the entire code path the returned arrays are used in or resorting to tricks already mentioned in this issue. Even then we would still probably run into issues with other libraries that don't have everything marked read only. I believe that mutating results is a valid use case and not something Slonik should prevent the user from doing. The only use case for a read only return value I can think of is if the returned object was a direct reference to some internal state that can be read but not modified. This is not the case here. I have a C++ background where If someone does wish to prevent their query results from being mutated they can do so by assigning to a read only variable or changing the return type of the function in their own code. I imagine most people write code similar to the example in the OP. This would avoid the issues caused while providing all the same benefits. |
@gajus I agree with encouraging the functional style, but I need to second the previous comment: making return values readonly makes it really difficult to work in the current TypeScript ecosystem, where readonly is not as widely used. Our team is currently discussing writing a wrapper around Slonik to change these types, because updating everything to use readonly would be too much work. |
@gajus This makes slonik near unusable for us as we would need to propagate the keyword |
(sorry this isn't a bug, but can't figure out how to remove the label)
I just upgraded to version
23.0.1
. I use typescript and was excited to see that the library had been re-written in typescript.Overall the upgrade seemed to go smoothly. However, on my
.many<MyObjectType>()
calls, I had type errors saying that the result was marked as readonly, and could not be cast to mutable typeMyObjectType[]
.I'm writing just to ask why this is the case. I'm able to get around this and return my mutable array type by spreading the results into a new array.
Here's a more complete example:
The text was updated successfully, but these errors were encountered: