TypeScript 是否有 bug?声明仅在以某些格式编写时才有效

tru*_*ktr 5 type-declaration typescript

.d.ts声明文件中,我尝试以四种不同的方式做同样的事情,但只有其中两种有效:

// Doesn't work.
declare global {
    const THREE: typeof import('three')
}

// Doesn't work.
import * as _THREE from 'three'
declare const THREE: typeof _THREE

// Works.
import * as _THREE from 'three'
declare global {
    const THREE: typeof _THREE
}

// Works.
declare const THREE: typeof import('three')
Run Code Online (Sandbox Code Playgroud)

'three'模块包含export namespace THREE.

在前两种情况下,其他.ts文件用作THREE全局时会出现错误'THREE' refers to a UMD global, but the current file is a module. Consider adding an import instead.

在这两种情况下,.ts使用全局的其他文件THREE不会出现这样的错误,并且它们THREE按预期使用我的定义。

fe,如果我在文件中使用第二个非工作选项.d.ts

// globals.d.ts
import * as _THREE from 'three'
declare const THREE: typeof _THREE
Run Code Online (Sandbox Code Playgroud)

然后在另一个.ts文件中:

// other-file.ts
console.log(THREE) // ERROR: 'THREE' refers to a UMD global, but the current file is a module. Consider adding an import instead.
Run Code Online (Sandbox Code Playgroud)

但如果我使用第四个(最后一个)选项,

// globals.d.ts
declare const THREE: typeof import('three')
Run Code Online (Sandbox Code Playgroud)

那么其他文件就没有问题了:

// other-file.ts
console.log(THREE) // no problem.
Run Code Online (Sandbox Code Playgroud)

为什么前两个选项不起作用,但后两个选项起作用?

Tit*_*mir 5

首先,让我说,鉴于此错误: ,您实际上可能对3.5 PR'THREE' refers to a UMD global, but the current file is a module. Consider adding an import instead.中的新编译器选项感兴趣(尽管我看到您对相关问题发表了评论,确保您没有错过修复)。allowUmdGlobalAccess

关于错误,这只是全局增强的工作原理以及什么是模块和不是模块的交集:

  1. global只能在模块中使用,global在脚本文件中不需要
  2. 如果文件包含importorexport语句,则它是一个模块,否则它被视为脚本文件。

给定这 2 个二元规则,我们得到您所描述的 4 种可能性

1. 不是模块,有global=> 错误。

declare global {
    const THREE: typeof import('three')
}
Run Code Online (Sandbox Code Playgroud)

由于该文件不是模块而是一个简单的脚本文件,因此 usingglobal是一个错误,因为该文件中声明的任何内容都将位于全局命名空间中,那么为什么要添加 呢global

2. 模块,无global => 未使用的模块常量

    import * as _THREE from 'three'
    declare const THREE: typeof _THREE
Run Code Online (Sandbox Code Playgroud)

由于该文件包含一个import模块,因此声明的 const 无论如何都不在全局范围内,因此它只是一个不会被使用的模块局部变量。您在其他文件中遇到的错误来自three模块本身(它声明了 UMD 全局命名空间)

3. 模块,具有全局性

import * as _THREE from 'three'
declare global {
    const THREE: typeof _THREE
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,文件是一个模块,但定义是在global扩展中。这意味着 的定义THREE将被放在全局命名空间中,并且在其他文件中可用

4.不是模块,没有全局

declare const THREE: typeof import('three')
Run Code Online (Sandbox Code Playgroud)

在最后一种情况下,无论导入类型如何,该文件都不是模块。只有导入语句才能使文件成为模块,而导入类型则不会。由于该文件不是模块,因此THREE声明的常量位于全局命名空间中,并且在其他文件中同样可用。


Mik*_* Kh 2

我也有这样的问题。 关联

对于tsconfig.json,您可以使用:

"compilerOptions": {
    "allowUmdGlobalAccess": true,
Run Code Online (Sandbox Code Playgroud)

它使编译器可以访问 UMD 全局变量,列出了三种类型。所以您不需要在之后导入或引用它。与 JQuery 或 $ 相同。