Ошибка TypeScript или нет? Декларация работает только когда написано в определенных форматах - PullRequest
4 голосов
/ 13 мая 2019

В файле объявления .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')

Модуль '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 global не имеет такой ошибки, и они используют мое определение THREE, как и ожидалось.

fe, если я использую второй нерабочий параметр в файле .d.ts:

// globals.d.ts
import * as _THREE from 'three'
declare const THREE: typeof _THREE

затем в другом .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.

Но если я использую четвертый (последний) вариант,

// globals.d.ts
declare const THREE: typeof import('three')

, тогда вдругой файл:

// other-file.ts
console.log(THREE) // no problem.

Почему первые два варианта не работают, а последние два работают?

1 Ответ

3 голосов
/ 13 мая 2019

Во-первых, позвольте мне сказать, что с учетом этой ошибки: 'THREE' refers to a UMD global, but the current file is a module. Consider adding an import instead., вам может быть действительно интересна новая опция компилятора allowUmdGlobalAccess в 3,5 PR (хотя я вижу, что вы прокомментировали связанную выпуск , убедившись, что вы не пропустили исправление).

Что касается ошибок, это всего лишь пересечение того, как работает глобальное расширение и что является и не является модулем:

  1. global можно использовать только в модулях, global не требуется в файлах сценариев
  2. Файл - это модуль, если он содержит оператор import или export, в противном случае онсчитается файлом сценария.

Учитывая эти 2 двоичных правила, мы получаем именно те 4 возможности, которые вы описываете

1.Не модуль, с ошибкой global =>.

declare global {
    const THREE: typeof import('three')
}

Поскольку файл не является модулем, а представляет собой простой файл сценария, использование global является ошибкой, поскольку все, что объявлено в этомВ любом случае файл будет находиться в глобальном пространстве имен, так зачем добавлять global?

2.Модуль, без global => неиспользуемая постоянная модуля

    import * as _THREE from 'three'
    declare const THREE: typeof _THREE

Поскольку этот файл содержит import, он является модулем, поэтому объявленный const никоим образом не входит в глобальную область видимости итаким образом, это просто локальная переменная модуля, которая останется неиспользованной.Ошибка, которую вы получаете в других файлах, происходит от самого модуля three (который объявляет глобальное пространство имен UMD)

3.Модуль, с глобальным

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

В этом случае файл является модулем, но определение находится в расширении global.Это означает, что определение THREE будет помещено в глобальное пространство имен и будет доступно в других файлах

4.Не модуль, не глобальный

declare const THREE: typeof import('three')

В этом последнем случае файл не является модулем, несмотря на тип импорта.Только операторы импорта делают файл модулем, а типы импорта - нет.Поскольку этот файл не является модулем, объявленная константа THREE находится в глобальном пространстве имен и доступна как таковая в других файлах.

...