TypeScript: module augmentation impossible
See original GitHub issueDue to typescript bug microsoft/TypeScript#18877
It is impossible to extend THREE.js class prototypes if they’re imported via Three.d.ts
(i.e. import { Object3D } from "three";
) using the method described here: https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
This has been brought up before, but as a a support question (#13425). I believe this is actually something that needs resolving through changes to Three, so have re-opened.
It looks as though the best solution to this as far as I can tell, is exporting an explicit list of names from Three.d.ts
like: export { Object3DIdCount, Object3D } from './core/Object3D';
(which does work fine if I modify the .d.ts
in my node_modules
)
Unfortunately this bug in tsc
was closed as a design limitation: https://github.com/microsoft/TypeScript/issues/9532
I want to know if you would be on board with exporting every name explicitly from Three.d.ts
, and how you would prefer to test that it works. I’m then happy to write a PR 😃
My suggestions are making it fully automatic, as a part of:
- https://github.com/mrdoob/three.js/blob/dev/utils/modularize.js
- or a new script
EDIT: Changed to clarify the problem.
Issue Analytics
- State:
- Created 3 years ago
- Comments:5 (3 by maintainers)
Top GitHub Comments
Thanks, that is clearer yes. I’m still confused about why this is the case in TypeScript, but perhaps that is beside the point.
Unfortunately, I don’t think we are able to maintain the more explicit exports in the way you suggest. That creates a fair bit more complexity managing files that are already quite difficult to manage and test.
Could I suggest that you consider other options here? For example:
A. Extend
Object3D
with inheritance, rather than modifying the prototype. B. Attach extra methods to a sharedObjectUtils
class, or perhapsobject.userData
(which is not shared between instances, though).The exact thing that I want to make work is the below:
Where I just want to be able to store extra information on every Object3D in my scene.
I’ve found this a very useful pattern in the past (in pure JS), often when trying to find some logical component which is responsible for something in the scene graph during a raycast query.
Unfortunately due to typescript bug microsoft/TypeScript#18877 this is impossible when Three.d.ts exports using
export * from './core/Object3D';
However if Three.d.ts names the exports explicitly like
export { Object3DIdCount, Object3D } from './core/Object3D;
then the augmentation to theObject3D
class prototype compiles fine.For now I’ve just worked around it by making pure-functions which take an Object3D as an argument and use
as any
but this is really awkward as an API - vs adding to Object3D’s prototype.