-
Notifications
You must be signed in to change notification settings - Fork 86
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
Feature: All Types as Readonly #221
Conversation
with TODOsAdjusted test and marked items with TODOsAdjusted test and marked items with TODOsAdjusted test and marked items with TODOsAdjusted test and marked items with TODOsAdjusted test and marked items with TODOsAdjusted test and marked items with TODOs
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
LGTM just a comment on this part:
if that output doesn't satisfy you, you can very well make your own |
Thank you so much for your feedback. Two items:
|
oh, I meant that you can do so without using tanu. like the example fn I wrote above and yes, I'm fine with merging as it is, given this doesn't break/impact current behaviour/users and is "just" an addition, I don't see a reason not to have it if it can help some people thanks for your work on this ! |
I do have 1 tiny request before merging so that other contributors can see the default behaviour first |
Of course. I have made the requested change to the order of the tests. Feel free to merge this at your convenience. Once this is merged, what is your release schedule? Or do you perform fully automated CI/CD releases? I only ask because obviously I'm eager to use this in my own personal work. :) Thank you again for your support of this addition to the project. |
ah, good catch. we use changesets so you can add one with |
Ok. Apologies for recapping, I haven't used this changeset tool before to drive a release process.
Thank you again. |
1 - yes |
Excellent. One final question: shouldn't it be a minor version bump (x.1.x) and not a patch version bump (x.x.1). My understanding of semantic versioning is that new functionality that is 100% backwards compatible would mean a minor version bump, whereas patch version bumps are just bug fixes to existing functionality. Its your project, I'll version it however you see fit. Just my two cents. |
both are fine with me tbh, I don't have a strong opinion here if you feel like a |
Ok, I believe I have made the correct changeset update. Can you confirm, and if so merge? If I made a mistake with the changeset, please inform me and I will correct it. Thank you again. |
Related To: #214
Rationale
Regardless of the OpenAPI specification for the types, when writing code with any types there are advantages to enforcing readonly on them. This is one piece of immutable programming design, where variables should never change after their initial declaration/assignment. Such an approach offers a variety of benefits in terms of readability and maintainability, and is the foundation of Functional Programming design patterns.
Adding the option to make all generated types readonly allows for users of this library who prefer to program with immutable design patterns to more easily integrate the output into their codebases.
Alternatives
It has been said that the OpenAPI schema definition could either be a) made readonly at the source, or b) parsed prior to passing into this library to make everything readonly. While this is certainly possible, there are disadvantages to this approach.
First, many OpenAPI schemas consumed by frontend applications are either not directly controlled by the frontend developer or are auto-generated by tooling in which this kind of fine-grained modification is not straightforward. While having the source OpenAPI schema be as accurate as possible is always an ideal solution to all openapi-type-generation efforts, ensuring that the schema enforces readonly across the board is not a solution that can be relied upon in all cases.
As for processing the schema prior to submitting it to this library, that is absolutely a solution that could be reliable in all cases. However, it puts more work on the developer consuming this library to take those preparations. In general, it would be highly beneficial if this library could automatically perform that operation without any pre-processing of the schema.
Implementation Overview
allReadonly
, has been added to this tool. When unused, it defaults to false. When set to true, all Zod schemas and generated TypeScript types will enforce readonly behavior across the board.--all-readonly
.Implementation Quirk - Readonly Arrays
This library contains the ability to generate TypeScript types as well as Zod schemas. When generating the TypeScript types, the Tanu library is used. I am new to Tanu, so if there is a better way to implement this that resolves the following quirk please recommend it. I was unable to find an alternative myself.
The Tanu library does not have the equivalent of
t.readonlyarray()
. As a result, to make an array readonly, I had to writet.readonly(t.array())
. This has two impacts on the output.The first is that the type produced is
Readonly<Array<T>>
, instead of the more traditionalReadonlyArray<T>
. While the latter is a bit cleaner IMO, the two types are identical and inter-changeable in all practical ways.The second is that, if an array is a property in an object, it will be double-readonly. All objects wrapped are generated as
Readonly<{}>
, rather than assigning thereadonly
modifier to each property. However, this approach to making an array readonly will add the readonly modifier to the relevant property if it is a member of an object. To further clarify, this is an example of the output:Yet again, from a practical perspective this does not have any impact on the functionality of the type. It is simply a weird quirk of how the Tanu library generates the type outputs.
Conclusion
I hope that this PR meets the standards of this project, and can be speedily adopted into what is already an excellent tool for the TypeScript community.