The heart of this issue, for me, is what is three.js intended for? If it’s simply a framework for creating cool demos, then it makes sense to target smaller projects which don’t need or care about strong typing.
However the value of strong typing increases with project scale. For projects like mine (a game engine >100K lines of code and counting), not using strong typing effectively makes the project infeasible. It is far easier and faster for me to code in TypeScript than JavaScript because there are a vast number of potential mistakes that I no longer need to worry about. (Especially since I tend to use all of the ‘strict’ compiler settings like nullability checks.)
To be honest, the way I read this announcement is that the maintainers of three.js have made a cost/benefit calculation such that they are willing to accept a lower quality bar for the type definition files in exchange for reduced maintenance effort. By offloading the maintenance to another repo and to other maintainers who have a higher interest level, they are essentially giving themselves permission to not concern themselves with keeping the type definitions in sync with the rest of the code.
I think it’s the former. Compared to the examples, it feels that there are very few resources on how to integrate three into a large project. There are many examples (all?) that could fall into the “cool demo” category IMHO. One thing to note is that three is not stable, hence, maintaining types seems like a burden since it imposes some stability.
This is a pretty valid decision. The library is still a javascript library, for javascript
FWIW and I’m no expert, it feels that your approach would bring us back to where we started, except with a different syntax? You want your IDE to pick up types, this has to be done using some additional syntax, be it flow, TS, JSdocs etc. Although curious on thoughts here.
Yeah, that’s correct, my motivation for the discussion is that I want my IDE to pick up types along with IDE help figuring out APIs without flipping back and forth to the online documentation. @donmccurdy said that jsdoc to type definitions wouldn’t work anyway, so it’s moot whether or not the jsdoc approach would be less or equal maintenance.
I would phrase this differently: the maintainers of three.js are not willing to also be the maintainers of TypeScript definitions for the library. The additional maintenance cost is too high.
The quality of the type definition files will depend on the willingness of those who use TypeScript to invest in maintaining those files. This is similar to the expectations for integrations with other frameworks, e.g. react-three-fiber and vue-threejs.
To be honest, the way I read this announcement is that the maintainers of three.js have made a cost/benefit calculation such that they are willing to accept a lower quality bar for the type definition files in exchange for reduced maintenance effort.
I’m also one of those nerds building an entire engine around Three and not having up-to-date type definitions is going to be a huge pain. I know from my professional experience that having to maintain two separate code-bases and keep them in sync is not-done. It will eventually grow apart, it won’t be feature-complete, etc.
Three is large enough to qualify as a perfect example of something that should be written in a strongly-typed language to begin with. It does make programming a lot easier and ensures developers don’t have to worry about accidental typing mistakes, thus raising the quality of the code base as a whole.
Seeing this - the decoupling of the type definitions from the main repo - because “the maintenance cost is too high” is a literal translation to: “We don’t care about the code quality, as long as the features we implement work”. It is essentially the same as documenting your code or writing unit tests. Sure you can skip those, but at what cost? Saving a little bit of development time versus a reliable code-base?
In my opinion there are two options:
Start porting Three to Typescript and be done with it. The quality of the code will improve, IDE’s can properly infer types, it can target different ES versions during compilation, etc. etc. There’s no downside apart from making the actual transition.
Drop typescript support entirely. Sure this will piss people off - myself included - but relying on “people that are interested” to keep the type definitions in sync with the main repo is stupid. It will eventually grow apart or trivial changes won’t be reflected in the definitions because “meh, its such a small change”.
I’ve seen similar workflows in my professional work-life more than once where a team has to make a project basically from scratch for whatever reason, but keep the feature-set in sync with each other. It doesn’t work. It never does, unless you either automate half of the process, or enforce people making a chance to also update the other part. The same goes for writing documentation. Did you make a new feature? Document it. Did you change part of an important core piece of the software? Update / write unit-tests. These things should be part of the workflow, not something that is optional.
This is not gonna happen. three.js is a JavaScript project. If you want a pure TS project, it’s probably better to work with BabylonJS or threeify (when it gets more mature).
The support was actually dropped in the main repository. However, the community of three.js is not restricted on the three.js repository. If three-ts-types gets enough support from the respective TypeScript developers, it should be realistic to keep the type declarations in sync for each new release.
I get that. But we started out having typescript declaration files in a separate repository. It got out of sync, or never was in sync to begin with. We solved this by integrating the d.ts files in the main repo with the main reason being “to remind people” to update these as well.
Now, two years later, like @mrdoob said, we did a good job. Why should we go back to the old situation, only to find ourselves in the same position again in a year or so? Simply relying on the community to keep this up-to-date is not feasible unless there is a dedicated team of people responsible for maintaining it. This honestly scares me.
Before the typescript declarations were in sync. At time of writing this, they are out of sync. 126 got released yesterday. @types/three yields 125.3.
That’s actually not true. Source code was often changed without doing the changes to the respective TS files. Simply because many contributors just work with JavaScript (like myself) and do not have the skills to author the TS declaration file.
This is explained in the first post.
Well, a certain delay is probably inevitable. If the TS files are so important to you, you should probably support three-ts-types . Or sponsor one of the contributors so they have more resources to work on the types.
I don’t think people understand threejs well enough. Typescript is probably the very antithesis of three’s philosophy. Three is a javascript project, and javascript is a dynamically typed language.
After all, it sounds that there was an open call for TS maintainers for a whole week before this decision was made, and no one volunteered
I think this is the only change. People that like TS should support three-ts-types, it really shouldn’t be that much work to keep track of the changes and update them in a different repo. There is a whole month between three’s releases.
… Or, if my development time allows it, contribute myself
You’re probably right. I’m honestly just scared because I’ve seen similar workflows gone wrong too many times in the past.I personally work exclusively with TS, which is why I’m so biased towards it.
I don’t know… Maybe I’ll get bored one weekend and write an analysis tool for the original three source and just create something that will generate robust TypeScript declaration files. Sounds like a neat little weekend project to pick up sometime in the near future.
First, BablyonJS is not an option - while it is a nice library, it is far too opinionated, and lacks the flexibility to do what I want. Like many libraries, it is very scene-graph centered, and is not a good fit for worlds where most of the meshes are procedurally-generated. (As someone who has a long history of experience writing games - I worked on The Sims 2 and Sim City 4 - I can say with confidence that professional-level games to a lot of this kind of thing for dynamic effects such as explosions, force-fields and so on. Implementing something like the building demolition effect - where the existing mesh is shattered into fragments - is considerably easier in a library like three.js)
I wouldn’t expect the maintainers of three.js to migrate to TypeScript since it is a fairly major undertaking. That being said, if it were my project I would not hesitate. I’ve been working with TS on a daily basis for 4 years now, and I see a lot of large projects are making the switch, both within the open-source world and within my current employer. Just having the ability to rename a variable in VSCode, and have it propagate the changes throughout the code base - without affecting other unrelated variables that happen to have the same name - is invaluable during refactoring.
The approach I would take would be to allow an incremental migration - the current src directory would become the compiler’s output folder, so existing JS customers would not be affected - they would simply use the precompiled .js files the same way they use the uncompiled .js today.
Then I would do a “leaves-first” migration, starting with the basic geometry types and the shaders, and then gradually work my way up the tree. This could utilize the existing type definition files during the transition.
Certainly there would be cases where finding the right type expression to fully replicate the behavior and the structure of the existing code base would be a challenge, but this is exactly what TS is designed to do - encompass just about every possible JS coding pattern - and there are plenty of experts on this board who could offer solutions and advice.
An announcement to all the folk on the discourse, firstly you’re welcome to contact me on the discord server on on the repo three-ts-types if you have any queries surrounding the types.
Secondly, I think it’s unfair to expect the types to be released the same day as the repo, the current workflow is as such: commit in three > found by TS maintainer > updated in three-ts-types, So without predicting the future, we’re probably going to be always behind. However, I am aware that DT can take a while to push through a change and i’m keeping this in mind, I also maintain R3F & related libraries so I like to be able to use the latest version of three too. Therefore, if it takes too long and I feel like it’s a waste of time, we’ll look to move away from DT so maybe watch the repo for updates.
Thirdly, It’s obvious that the maintainers of three do not want to undertake the maintainance of the TS types and we’ve got to respect that, people don’t keep telling Facebook to move React to Typescript? Or if they do they ignore it because they use Flow. So if you want to discuss better ways of updating the types, why not raise a discussion on the the TS repo we have (I don’t check here and only saw the tag). We’re open to new ideas.
Finally, anyone’s welcome to contribute, the more people we have the quicker the updates, you can’t complain if you’re not willing to be involved imo.
If you were to give a guesstimate, how far behind would the types be behind three? If it’s two versions that’s only two months. If I were to guess I’d say that most people don’t update three nearly as often. I’m actually surprised when I find people that are updating it constantly.
Right now r126 has an open & ready to merge PR on DefinitelyTyped you can track the status of this here. For more updates on the progress of three-ts-types I suggest you check out the repo here