-
Notifications
You must be signed in to change notification settings - Fork 224
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
Defaulted values are not correctly copied for record
type data.
#1238
Comments
Thanks for the report @MaddyGuthridge! I've tested this locally and I get the same issue. After testing this a bit I think the easiest solution for this is to call export function defaulted<T, S>(
struct: Struct<T, S>,
fallback: any,
options: {
strict?: boolean
} = {}
): Struct<T, S> {
return coerce(struct, unknown(), (x) => {
// To avoid a pass-by-reference bug, we'll clone objects when encountered
// here, but the for performance avoid cloning primatives and functions
const f =
typeof fallback === 'function'
? fallback()
: typeof fallback === 'object'
? structuredClone(fallback)
: fallback WDYT? cc: @arturmuller |
@MaddyGuthridge thank you for the report! @yeoffrey hmm. Using a custom class is probably a very rare use case, but also doesn't seem impossible. I personally exclusively use POJOs with Superstruct, but... I guess someone somewhere could be doing something that this change could completely break. I am honestly just leaning towards a warning in the docs, pointing people towards using the factory function signature for non primitive objects. My guess is that it was added exactly for this reason, just not properly documented. |
@arturmuller Alternatively we could accept only a callback function. That would be a breaking change but to me this feels like a bit of a foot gun 😅 Up to you! |
I may actually have a suggestion for this: a library maintained by one of my coworkers |
This could be a good solution. I could try modifying #1248 to include that code. Thanks for the link! |
When providing a default value for a
record
-type struct, the default value is not properly copied, meaning that it is at risk of subtle pass-by-reference bugs.Consider this example:
The current behaviour of a
defaulted(record(...), ...)
is different compared to that ofdefaulted(object(...), ...)
anddefaulted(array(...), ...)
which both appear to copy their input data.The text was updated successfully, but these errors were encountered: