javascripttypescriptthree.jstype-declaration

How to override a TypeScript UMD global type definition?


I have installed three@^0.103.0, which has its own type definitions.

In src/global.d.ts of my project I have:

import * as _THREE from 'three'

declare global {
    const THREE: typeof _THREE
}

Then in src/global.ts I have

import * as THREE from 'three'
(window as any).THREE = { ...THREE }

Then in src/my-code.js I am trying to use the THREE as a global variable, f.e.

console.log(new THREE.Vector3(1,2,3)) // ERROR, 'THREE' refers to a UMD global, but the current file is a module. Consider adding an import instead.

It tells me that 'THREE' refers to a UMD global, but the current file is a module. Consider adding an import instead..

When I jump to the definition of THREE, it takes me to node_modules/three/src/Three.d.ts, which is not my src/global.d.ts file.

So, it seems like TypeScript is ignoring my global.d.ts definitions?

My tsconfig.json contains

  "allowJs" true,
  "checkJs" true,
  "include": ["src/**/*"]

and I have global.d.ts is inside of src.

If I add

/// <reference path="./global.d.ts" />

to the top of src/my-code.js file (JavaScript), then it works, and I can jump to the definition of THREE which takes me to my global.d.ts file.

Why does it not work without the reference comment?


Solution

  • The above should work. There's only one small gotcha:

    The two global files have the same name! (i.e. global.ts and global.d.ts)

    In this case, TypeScript seems to merge them together (or something), and thus seems to treat global as the same module (as in import './global' being ambiguous).

    So, by renaming one module to a different name, it all works.

    For example, rename src/global.ts to src/make-global.ts, and leave src/global.d.ts, and it will work.

    I was pulling my hair out wondering what was going on until I renamed one of the files.