This summer I got an awesome opportunity to work on zulip/zulip and help migrate its javascript code to TypeScript. Our goal was to convert untyped JS files to TypeScript, parse any type-unsafe data we encounter (including data recieved from server), using zod, refactor code, improve tests and fix bugs catched during the migrations. The result - a frontend codebase that is more readable and robust.
I believe challenges are very subjective and they change based on the developer as much as based on the project itself. For me the biggest challenge was to make sure that my changes/refactors do not change code behaviour. Although this sounds simple, I think it is one of most common mistake that developers make, especially when migrating a codebase from one language/framework to another. We sometimes enforce our changes on the code, just to get that migration out-the-window and it results in degradation of code-quality.
Also I should mention, that there are a lot of other complex challenges that arise while migrating a huge codebase like Zulip's for ex. complex import cycles. But thanks to our past gsoc participants, core members and contributors I did not have to face them.
Things could have been more challenging if we didn't have an API structure as good as Zulip's. It helped us create clean types utilising TypeScript's features like unions, partials, omits aptly.
My work for Zulip included js file migrations, writing helper functions to generate better test data and fixing bugs caught during migrations. My familiarity with Zulip's codebase and its extremely helpful community helped me to contribute even before coding period officially began ie. during the community bonding period.
Also for the sake of simplicity I am dividing my work into subcategories.
- PRs migrating js files to TypeScript.
- PRs creating helper functions to generate better test data.
- PRs fixing bugs.
- PRs with my "buddy" reviews.
Quick Links-
- Commits during coding period
- PRs during coding period
- All commits for Zulip/Zulip
- All PRs for zulip/zulip
-
#30209- starred_messages_ui: Convert module to TypeScript.
Size: M | Lines added: +32/-11 -
#30263-settings_stream: Convert module to TypeScript.
Size: L | Lines changed: +39/-30
- #30323-navigate: Convert module to TypeScript.
Size: L | Lines changed: +39/-25
- #30378-stream_create_subscribers: Convert module to TypeScript.
Size: M | Lines changed: +18/-15
- #30380-user_group_create_members: Convert module to TypeScript.
Size: M | Lines changed: +17/-14
- #30412-stream_edit_subscribers: Convert module to TypeScript.
Size: XL | Lines changed: +109/-44
-
#30459-emoji_picker: Convert module to TypeScript.
Size: XL | Lines changed: +192/-134The first commit of this PR fixed an UI bug we were encountering while searching for emojis in emoji box. The order of emojis was inconsistent before and after typing the search words, the unpopular emojis were being prioritised above the popular emojis. This closed issue #30439. The rest of the commits were for migrating the module
emoji_picker.js
to TypeScript. -
#30496-user_group_edit_members: Convert module to TypeScript.
Size: XL | Lines changed: +92/-43
-
#30702-echo: Convert module to TypeScript.
Size: XL | Lines changed: +256/-144This migration was my most important work of the summer. The module
echo.js
is responsible for locally echoing (i.e. having the message appear in the feed the moment the user hits send, before the network round trip to the server) the messages. Also it handled other important code paths responsible for resending the messages failed due to network issues or other reasons. The PR also consituted significant code refactoring. #30702(commit) was particularly important -- it removed code blocks that handled zephyr mirroring in the frontend. -
#31145- message_event_util: Convert module to TypeScript.
Size: L | Lines changed: +47/-18
-
#31235- example_user: Create helper functions to create test user.
Size: XL | Lines changed: +96/-24 -
#31006- make_message: Add function to generate valid test messages.
Size: XL | Lines changed: +276/-0
-
#30905- Preparatory commit for #30509 and #30702
Size: L | Lines changed: +90/-0This PR created a new module
server_messages.ts
which holdszod
schema for the incoming messages from the server. We parse these messages at the API boundaries so the downstream code is type safe. -
#30521- stream_edit_subscribers: Use raw_data and data more.
Size: L | Lines changed: +26/-28 -
#30735- user_group_edit_members: Initialise users data as empty array.
Size: L | Lines changed: +6/-6 -
#30288- settings_streams: Fix error thrown when adding default channels.
Size: L | Lines changed: +8/-5
- #30018 settings_profile_field: Convert Module to TypeScript.
- #30685 user_group_create: Convert Module to TypeScript.
- #30899 landing_page: Convert Module to TypeScript.
- #30873 help: Convert Module to TypeScript.
- #31142 integrations_dev_panel: Convert Module to TypeScript.
- #30509 message_fetch: Convert Module to TypeScript.
- #31384 settings_bots: Convert Module to TypeScript.
- typescript migration
- typescript node tests
- Varun Singh(LaPulgaaa) Checkins
- Default channels Add channel modal error
There is still a significant portion of the frontend codebase that is unmigrated. Once the codebase is completely migrated to TypeScript, it would be worth doing a second pass on all the migrated files cleaning up the types and making them more strict. We are also planning to convert our node test to TypeScript. But it is a more long term project because of some hindering dependencies that we use for mocking js files.
We have also started writing helper functions to generate test data that satisfies the type definition and is more real world. Since the end goal is have every frontend data structure typed and parsed (using zod) we have to make sure that our test data are representative of actual data. These helper functions take some necessary fields and produce a completely type safe test data in return.
I consider myself extremely lucky to have gotten a chance to work with the Zulip team professionally. The entire community is very welcoming and helpful. Getting a chance to learn from the extremely talented team here has certainly made me a better developer.
Working on this project has drastically improved my TypeScript knowledge. I understand the language and its features better and hence am able to write more type safe code.
Apart from the technical skills, I learned how to self-review my work, review other's work, propose ideas in a clear and understandable manner and be a team player in general.
It was truly an honor to work with the team and contribute to the project. I would like to thank my mentor @Lalit3716, my buddy @afeefuddin and our lead developer @timabbott for all the code reviews and feedbacks. I am also grateful to Google for the opportunity.