question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

TypeScript: module augmentation impossible

See original GitHub issue

Due 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:

EDIT: Changed to clarify the problem.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
donmccurdycommented, May 27, 2020

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 shared ObjectUtils class, or perhaps object.userData (which is not shared between instances, though).

1reaction
willstott101commented, May 26, 2020

The exact thing that I want to make work is the below:

import { Object3D } from "three";
import { Entity } from "./Entity";

declare module "three" {
  export interface Object3D {
    entity?: Entity;
    findOwningEntity: () => Entity | "world";
  }
}

Object3D.prototype.findOwningEntity = function () {
  if (this.entity) return this.entity;
  let p = this.parent;
  if (p) return p.findOwningEntity();
  return "world";
};

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 the Object3D 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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

node.js - Typescript - can't augment a module - Stack Overflow
TypeScript apparently only allows module augmentation of ES modules (see example down under), above syntax explicitly creates a Node CommonJS ...
Read more >
Solve any external library error in TypeScript with module ...
This TypeScript tutorial will cover how we can use module augmentation to solve any type errors you might encounter when working with ...
Read more >
Documentation - Modules - TypeScript
How modules work in TypeScript. ... module gets to pick the name that they will use to refer to the module, so accidental...
Read more >
Michael Jackson on Twitter: "TypeScript experts: how do you ...
TypeScript experts: how do you normally patch a type that is missing ... you can use module augmentation and declaration merging. import ......
Read more >
Module Augmentation With Exported Functions : r/typescript
The TypeScript module augmentation you are talking about is only for augmenting the TYPES of a module, NOT the actual code. An example...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found