7

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?

trusktr
  • 44,284
  • 53
  • 191
  • 263
  • So, you're overriding the global `THREE`? What reason is there for doing this? – Andrew Eisenberg May 13 '19 at 00:05
  • @AndrewEisenberg There is no global THREE; I want to import it into my `global.ts` module and make it a global. But then in my `src/my-code.ts` file I get the error `'THREE' refers to a UMD global, but the current file is a module. Consider adding an import instead.`. How would I import THREE and make it global in the one module, and use it as a global in the other modules? – trusktr May 13 '19 at 00:28
  • Mohamed Hegazy said "a module (i.e. a file with at least one top-level import ot export) has its own scope, and declarations inside this file are not visible outside it unless exported." over at https://github.com/Microsoft/TypeScript/issues/21344#issuecomment-361498890. Is this the problem? That I'm importing THREE in a module and declaring a global, and this definition is not visible outside the file (unless I use `reference` for example)? How do I get the definition from `'three'` and make it a global? – trusktr May 13 '19 at 00:58
  • @AndrewEisenberg I think there's just something wrong with my setup: even if I put nothing but `declare var foo: number` in my `global.d.ts` file, then in any other `.js` file I try `console.log(foo)` and it complains that it can not find `foo`. I think I might just close this question. – trusktr May 13 '19 at 05:43
  • @AndrewEisenberg Oh, I see the problem. I have both `src/global.ts` and `src/global.d.ts`, which TypeScript apparently merges into one (or something). As soon as I renamed them differently (f.e. `make-global.ts` and `global.d.ts`), then it all started working. I was pulling my hair out. – trusktr May 13 '19 at 06:04

3 Answers3

8

For three.js you could declare compiler option allowUmdGlobalAccess in tsconfig.json:

"compilerOptions": {
    "allowUmdGlobalAccess": true,
}

This will give typescript access to your project global UMD, where three.js is listed when you install it. Then you could use it at your project same way as for example JQuery.

If this option not available - update your typescript.

Some details

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
Mikhail Kh
  • 176
  • 1
  • 8
2

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.

trusktr
  • 44,284
  • 53
  • 191
  • 263
  • You've correctly identified the source of the error, but your solution is unnecessarily complex since you should might as well place all of the code a single file `src/global.ts` file. I go into detail about the subject in this answer https://stackoverflow.com/a/43674912/1915893 – Aluan Haddad Jul 16 '19 at 14:14
  • @AluanHaddad Good info there. Thanks! – trusktr Nov 14 '19 at 04:23
2

You should check TypeScript typings resolution strategy in the handbook.

As state there, .ts files have precedence upon .d.ts.

(just bumped into the same problem myself)