如何声明对运行时 JavaScript 包中可用的现有命名空间的引用

How to declare reference to an existing namespace which is available from JavaScript bundle at runtime

我正在为现有的 JavaScript 应用编写插件 - Forge Autodesk.Viewing

在版本 6 之后,他们将 THREE.js 包含在他们的应用程序包中。

现在我可以像这样将它与我的插件一起使用:

declare var THREE:any; 

但我丢失了所有类型,所以我通过以下方式安装 three.js:

npm install --save three

我可以使用三个并导入它,但我不需要导入它,因为我的主应用程序中已经有了它。我需要做的是引用类型,所以我尝试做这样的事情:

    declare var THREE:THREE;
//Cannot use namespace 'THREE' as a type.

然后我尝试:

/// <reference types='three' /> 效果很好,但是:

        const planes:THREE.Plane[] = []; //this line is okey

        planes.push(new THREE.Plane()); //but this says
        
        //'THREE' refers to a UMD global, 
        // but the current file is a module. 
        // Consider adding an import instead.

Tsc 坚持我们应该导入它:

import * as THREE from 'three'; 

它编译没有任何问题,但是当我启动应用程序时它崩溃了,因为它试图获得 THREE.js 的另一个实例,我没有提供它,因为我在主应用程序中有它。

如何声明正确的引用并将类型保存到主 JavaScript 应用程序可用的命名空间?

Ypu 需要导入三个模块: 像这样:

import * as THREE from 'three'; // or import THREE from 'three';

var THREE = require('Three').

并使用 webpack 或其他模块加载器 (!)

如果您想手动包含 THREEJS 分发文件并使用不带模块的 TS 绑定(类型定义)(不推荐)- 您可以将 Three.d.ts 文件包含到您的项目中(与其他 THREEJS d.ts文件)并将其与三个斜杠 ref 一起使用。例如:

/// <reference path="..\..\node_modules\@types\three\index.d.ts" />

注意:在这种情况下,不要使用 "import" 或 "require" 导入三个命名空间。

Forge Viewer 有一个 TypeScript 定义文件 (.d.ts),您应该可以将其与 THREE.js 定义文件一起使用:https://forge.autodesk.com/blog/typescript-definitions-forge-viewer-and-nodejs-client-sdk-now-available.

如果您有以下问题:

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

(about UMD)

您可以尝试使用 tsconfig.json 中的选项:

"compilerOptions": {
    "allowUmdGlobalAccess": true,

(about config options)

这将使编译器能够访问全局 UMD,因此在这种情况下您不需要导入或引用此类模块。

three.js 的情况确实如此,他们已经将三个命名空间作为模块添加到 UMD 全局范围。所以如果你需要包含这个模块你应该导入。如果您只想参考,您可以使用此选项。如果打字稿在配置中无法识别此选项,请更新您的打字稿。

npm install typescript

感谢亲爱的 SalientBrain 和亲爱的 Petr Broz 的关注和帮助。