two.js: [Bug] Cannot import two.js in typescript project
Describe the bug I guess this is a continuation of #526. The generated types in two.js@0.7.5 don’t work right off the bat. At least not with the default create-react-app typescript setup.
To Reproduce Steps to reproduce the behavior:
npx create-react-app twojs-demo --template typescript
cd twojs-demo
npm i two.js@0.7.5
- Replace
src/App.tsx
with the following:
import { useEffect } from 'react';
import Two from 'two.js'
function App() {
useEffect(() => {
const two = new Two({
fullscreen: true,
autostart: true,
})
const container = document.getElementById('container');
if (container) two.appendTo(container)
var rect = two.makeRectangle((two as any).width / 2, (two as any).height / 2, 50 ,50);
(two as any).bind('update', function() {
rect.rotation += 0.001;
});
}, [])
return (
<div id='container' />
);
}
export default App;
- Observe the error:
File 'twojs-demo/node_modules/two.js/types.d.ts' is not a module.
Potential fix
Modify node_modules/two.js/types.d.ts
with the following changes:
- declare namespace Two {
+ declare module 'two.js' {
+ export default Two;
...
Reload the dev server or resave App.tsx to enact HMR. The code should run with no problems.
Notes
Besides not being able to import two.js, the type definitions were lacking the .width
, .height
, and .bind
attributes of a new Two()
instance. That’s why the App.tsx
casted (two as any)
. There might be other small problems like that.
I never used the jsdoc typescript generator, but perhaps there is a way to switch to declare module
instead of declare namespace
? I think ‘module’ is more modern in typescript (I would have to double-check).
Additionally, there should be a new version of @types/two.js
to mention that that package is just a stub file since you are including types here. I can open a PR over there if you are ready to take that step.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 2
- Comments: 18 (10 by maintainers)
v0.7.3
explored types generated usingtsc
andv0.7.4
used the current implementation of jsdocs to types, but because the location of thetypes.d.ts
file changed and I forgot to change the location in the package.json, it wasn’t included in that package. I’ll release a new version today that has these types removed so that people can continue to use@types/two
.@CaelanStewart, the latest on npm should have a placeholder
module
declaration for Two.js so that you can at least load the latest version of Two.js into a TypeScript project. This will have to do until I’m able to finish porting everything to ES6class
declarations which will make the TypeScript declarations more accurate through TypeScript’s own types generation script.Apologies to all for the delay. I’m not a TypeScript user, so this has been a crash-course for me on TypeScript.
Small update (2 years in the making), the ES6 branch is now passing all tests: https://github.com/jonobr1/two.js/tree/es6
Gonna give it a couple of days before merging this into dev and updating the node package. This is your time to chime in!
Hopefully, v0.8.0 fixes many of your issues. It’s available now through npm.
For those interested, the WIP types now live here: https://github.com/jonobr1/two.js/blob/0b86fe087ef7f23a03bac828ea26d3e14712c83d/types.d.ts
If you happen to drop it in when developing and you see something, I’d love to get your feedback. Thanks!
Amazing, thank you @aaron-harvey. I was able to resolve the other issue as well (there was a conflict of statically assigned properties, so I moved them). I’ll try to spend some more time looking into why the
group.render
method triggers this. The other renderers have the same format for defining render calls, so it’s surprising that either the other renderers also don’t trigger an error or that the webgl renderer does.Also, to set expectations:
I finished writing the ES6 branch and with these changes the TypeScript Declarations will be more accurate. But, the tests are failing, so I still need to remedy those before publishing this. Baby steps!
There is something wonky in the
webgl.group.render
method that is causing the type checker to fail. I wasn’t able to track down the exact cause, but I did manage to satisfy the type checker adding the following type hint:Yeah, I removed those types because I’m in the middle of porting all the modules to ES6 classes. This will yield better types inference. I must’ve mistakenly kept the package.json types file reference even though I removed it from the package. Sorry about that! I’ll look into that today.
Also agreed. At the moment though, typescript uses the types generated in
v0.7.5
even if@types/two
is installed. And so upgrading fromv0.7.4
breaks existing typescript code.One aspect I think would help a lot is to convert raw prototypical classes to use the class-keyword syntax. Typescript does a good job of picking up attributes set using
this.attr
in the constructor and other methods.