Initial pass of adding Typescript
Adding Typescript support to the React project as per (my own 😆 ) issue https://github.com/lvgl/lv_binding_js/issues/36 and also saw the comments here https://github.com/lvgl/lv_binding_js/issues/14#issuecomment-1663182201.
I wanted to add Typescript to the importable/public API so when consuming lvgljs its easy to see which components and APIs are available.
Example:
https://github.com/user-attachments/assets/aba0dfe5-00b2-4b51-9000-2bdedfa29940
Adding types
In this PR I've done an initial first pass at adding types across both the components as well as each of the styles. I've done the best I could to generate both the Prop Types as well as the Style Types based on available methods and also reading through the documentation. Something that might be good is to go through and compare to the Javascript generated by the .cpp files, but I'm not that familiar with C++.
I fully expect this to be a work in progress. I was trying to do the most useful types first but there are still lots of .js files across the codebase. Fortunately Typescript implementation can be somewhat progressive, in that .js and .ts files are interchangeable and I haven't turned on any build errors or linting rules for Typescript yet. We can view it as a useful enhancement/nice-to-have right now while we build out the full types.
As part of this, I've done my best to not modify any actual implementation - I've only added additional type annotations. There aren't any actual logic changes in the source code. There are quite a few errors/bugs that Typescript has identified so will do my best to address them in future PRs.
With that said, this already should be useful for consuming projects. E.g. looking at demo/hello_world/index.tsx we can see it both defines prop types for each component, as well as valid styles.
Build/import changes
I did make some slight changes to imports/builds to make Typescript work, and this moves to a more standard pattern of importing projects.
- Remove the
lvgljs-uialias inbuild.js - Instead, import the
/src/render/react/package.jsonproject aslvgljs-uiin the root/package.json - This allows Typescript to properly import and understand types
- Add
react-reconcilerandreacttypes
Future PRs/TODOs
- [ ] Convert rest of JS project to Typescript
- [ ] Add Typescript errors/linting to build scripts & pipeline
- [ ] Fix bugs/logic errors identified by Typescript
- [ ] Refactor/remove some of the unused methods (eg a lot of the methods in each
config.tsfile aren't required and are duplicated) - [ ] Manually or automatically (open to ideas?) generate types of the Native components from C++
Thanks for reviewing, I've tried to keep this to a small scope (types for components + styles only) but I realise its still a big PR 😅 . This PR definitely needs to be squashed before merging. Hopefully this makes using lvgljs much easier for consumers!
I'm sooo excited about this!! I'll take a look sometime this week, but thank you so much!!
We should probably add a tsconfig file and as part of that include txiki.js typings as well such that the runtime typings are also available.
Something else I'd like to do is to create a shared types file where we can define common types for the events:
Making those reusable will clean up a lot of typings. Also, beware that while stopPropagation is available, target and currentTarget aren't.
For the C++ code I think I have an idea on how to generate types from it using the macros. At this point I almost feel like we're reinventing JSI and React Native 🤣 but that's sort of the goal I guess. But it could also be as simple as hardcoding them in .d.ts files. That's a problem for the future though.
So far I like this. I've been testing locally and it works. My only nits are really the tsconfig (my editor does not know what to do without one), txiki runtime types and the events duplicated everywhere. If you can address these I think we should be able to merge them and evolve from there.
Have addressed your comments by adding the tsconfig.json file, the tiki runtime types and shared types for OnChangeEvent and OnClickEvent - I couldn't see where the Select event was supposed to be used (onPress?) so I didn't do that one but added the other two.
For something like onClick its implemented in the common API, and then again in some components. I don't think it needs to be implemented in each component if its in the base one but I didn't want to change any logic so can address in future.
@derekstavis were you wanting to merge this still?
Yes @Samywamy10 - there are a few conflicts on package.json, I can merge once you fix them
@derekstavis fixed the conflicts
Hi all, hi @Samywamy10, I just discovered this repo and I ran into minor trouble with typing in flexboxes with TypeScript. Also flex-grow wasn't triggered correctly, because it was short-circuited by the flexbox check at the top of pipe/flex.ts. Suggested patch attached at the bottom, feel free to git-am(1) it (or not :zany_face:).
Thanks for everyone's hard work on this amazing library and thanks to everyone involved for y'all's contributions to the open source community! You absolutely wonderful people :grin:
@Samywamy10 sorry dragging this but want to add the patch above? Happy to merge it. Also, if you're interested in helping this repo by becoming a contributor so you can merge your own PRs, you're welcome to!
@derekstavis I have a couple more patches in the roster, because I'm porting this baby to the Nintendo DSi, so stuff like dual screen support is a must there, ironing out some stuff…
I'm porting this baby to the Nintendo DSi
This is amaaaaazing!!
Aight @I-asked -- what about I merge this PR as is and you can push your changes as a new PR?
Thanks for merging :)