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
[RFC] TypeScript rewrite of a few Final Form packages #486
Comments
These all look like sane decisions and an evolution of the project. Regarding monorepo, it may have originally been split individually for scale/framework/scope creep/maintenance concerns. So, e.g. adding a vue based project might not be something you want to do in a monorepo (mixing with react and others). This is my only reservation with your structure. So my recommendation might be a final-form monorepo, a final-form-react monorepo etc. My worry about this repo is that it might go unmaintained, and we use it quite heavily. In fact I'm updating our libraries and this is on my watchlist to make sure everything is healthy. If this repo becomes unmaintained, we'll keep your repo in mind. I'm just one user, but I would like to see your work incorporated into the original body of work with you added as a maintainer. @erikras is this idea of interest to you? |
Hello! 🙂
I've rewritten a few Final Form packages in TypeScript, and I thought I'd share the results here.
This post is quite literally a request for comments 🙂
I'm writing this issue because I've done quite a bit of work over the past few months on this rewrite, so obviously, I want other other people to have the chance to enjoy the fruits of my labor and not just me 😄 I was also wondering if my project could be useful for the future of the Final Form community as a whole. Perhaps it could be merged into the original libraries at some point? I would like it to be! So I'm very open to any feedback that anyone might have about my rewrites, if you have any.
You can see my forked code here, at my final-form-ts repo.
You can also try out any of the TS packages by downloading them from npm, e.g. "@deckstar/final-form".
I originally posted about my rewrite project on the Final Form Discord channel a few months ago. Then, a few days ago, I noticed that there have been some calls for rewriting the library in TypeScript (e.g. #448, or for React Final Form #1028), so I thought I'd share my work here. Thus this RFC was born!
Summary of changes
The libraries I refactored were:
Because these are the ones I've been using in production.
While rewriting the packages, I ended up making quite a few changes to the project's structure and typings. However, the run-time code changes have been very minimal (almost none). Off the top of my head, these are the main changes that I introduced:
Library changes
Run-time changes
Almost none, except:
status
state, asetStatus
action and aninitialStatus
config prop.status
API. I was rewriting a project from Formik to Final Form for performance reasons, and because Formik had been dead for 2 years.Typing changes
Here is where the bulk of the work was done.
One feature that I'm quite happy about, is that I added JSDoc comments to a lot of the user-facing types. So now, if you hover over things like
values
,active
orinitialValues
, then you should get the same documentation as from the Final Form website right in your IDE.Most of the typing work was done with rewriting the generic arguments for types:
Subscription
a generic parameter:undefined
. However, the type is always{{type}} | undefined
, which is misleading. It's also dangerous: people can mark variables as non-nullable (e.g. to avoid checking forundefined
at runtime), and then forget to handle the case if the subscription changes.| undefined
added on to the type.InitialValues
as a generic. Personally, I never found this very useful and I think it just slowed down development without providing much type safety. Instead, I hardcodedinitialValues
to just bePartial<FormValues>
. I figured that if anyone needs something else, they can just cast the type later (e.g.const initialValues = form.initialValues as MyInitialValues
).Mutator
s, includingBoundMutator
types, to help handle the types of functions before and after they were bound to the form API.FieldConfig
can now take inFormValues
as an optional second generic parameter. This helps with props likegetValidator
, which allow access to form values.InputValue
generic parameter as often as theFormValues
, and that using theInputValue = FieldValue
default case was good enough for most situations. So I movedFormValues
ahead ofInputValue
.I realize that a many of these changes wouldn't play very well with the existing libraries (especially the monorepo refactor and reinitialized version numbers). Please understand that I was initially planning on using this TS version in a single private project only.
It was only when I realized how satisfied I was with it that I thought that other people might like it too. At the very least, I know I'd personally love to use it at work. But obviously my team probably wouldn't take too kindly to me promoting my pet project over an established library, and for good reason 😄
If any maintainers have time to have a look, please let me know what you think about any of this 🙂
PS: Also, please note that a few tests are currently broken: some of them fail because they fail to import from other packages in the monorepo (Jest is throwing(never mind, solved it 😄)Cannot find module
errors). I've tried a lot of fixes to no avail. If anyone could help me fix that, that would be awesome 😄 I can confirm that they do pass if the imports are resolved, though.The text was updated successfully, but these errors were encountered: