Replies: 1 comment 1 reply
-
Although very interesting (and I also have a validation helper using zod There are just too many use cases that trying to be one-size-fits-all would be very complicated and probably impossible. Much better to let the developer choose the solution that fits their needs. And although I agree that you should validate data on requests, forcing you to add validation would be a huge barrier to entry for somebody trying out Remix, or even just creating simple projects. Anyway, just my 2c. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
action
s accept untrusted user input, so many actions follow this recipe:action code from jokes tutorial illustrating this pattern
Since this is a common pattern, it would be helpful to either:
action
that ensures the user validates the data.The second is inspired by some experimentation I was doing with Socket.IO types using Nominal Types to force the developer to call a context-specific runtime validation function.
In other words, it's a strategy to bridge compile-time and run-time typechecking. The typechecker knows where the untrusted data boundaries are, and demands you to call the appropriate validation function before you're able to use the data.
It might look something like this:
Replace:
with:
this would then prevent you from directly accessing
request.formData()
, and would force you to pass the request throughbefore using it like:
Below, you'll find a working prototype of such a type powered by
zod
as the validator. The internal implementation (sandwiched between theINTERNAL IMPLEMENTATION
comments), is a bit fun (?) to follow (but not user-facing1); however, I walk through it (in the context of Socket.IO) here building up from first-principles-ish to explain how the types are constructed to help us achieve the goal (and how they combine together).After looking at the prototype below and the comments, it's important to note, the developer's steps are only:
PostSchema
) withzod
.ActionArgs
withActionArgsWithFormDataValidation<typeof PostSchema>
await validatedFormData(PostSchema, request);
and the way all the types are glued/constructed, PostSchema drives all the inferred types, so things cannot get out of sync and compile (since the typechecker will tell you where to sync things up).
Prototype
Additional Comments
request.url
and other "safe" fields are accessible without any validationRelated Links
loader
type inference #3276cc: @colinhacks, @mattpocock, @ryanflorence since it looks like there's been lots of type-related discussion amongst y'all!
Footnotes
Except for the compiler errors which you can see samples of in the code snippet 🤮 ↩
Beta Was this translation helpful? Give feedback.
All reactions