Typescript: Разрешить объявление определений модулей как глобальных переменных

Созданный на 15 мая 2015  ·  11Комментарии  ·  Источник: microsoft/TypeScript

У меня есть файл определения типа React (который объявлен с помощью внешнего модуля). В своих исходных файлах я обычно делаю:

import * as R from "react"

а затем с радостью можете использовать R.createElement(... т. д. в строго типизированной манере. Я даже умею:

let _r = R;
_r.createElement(...

Я хочу, чтобы не нужно было импортировать R в каждый файл, а вместо этого иметь его в качестве глобального объявления (да, я готов использовать глобальное пространство имен с помощью нескольких переменных). Я пробовал в .d.ts :

import * as React from "react";
declare var R : React;

Это не работает, я получаю сообщение «Не могу найти имя React». Есть ли другой способ экспортировать весь модуль как глобальный без изменения подчиненного response.d.ts?

Question

Самый полезный комментарий

Привет, @Evertt, действительно, я тоже получаю эту ошибку. Изначально в моем исходном коде не использовался синтаксис модуля ES6, но как только я переделал некоторые файлы в соответствии с этим синтаксисом, я получил ту же ошибку. Провел небольшое исследование, и то, что сработало для меня сейчас, - это когда я создаю второй файл globals.d.ts и помещаю его также в папку typings:

import * as _R from 'ramda';
import * as _mobx from 'mobx';

declare global {
  const R: typeof _R;
  const mobx: typeof _mobx;
}

Фактически, один только этот файл, кажется, "удовлетворяет" компилятор машинописного текста, поэтому теоретически вам не понадобятся другие файлы, о которых я упоминал ранее. Однако в моем конкретном случае (я использую WebStorm), когда у меня был только файл globals.d.ts, моя IDE постоянно проверяла меня, чтобы импортировать модули, а также завершение этих глобальных объектов было неполным. Итак, я в основном сохранил оба файла в каталоге typings, который соответствует машинописному тексту и моей IDE. Не очень хорошо, но для тех немногих глобалов, которые обычно используются, я думаю, что эти файлы можно поддерживать.

Это мой tsconfig.json для справки:

{
  "compilerOptions": {
    "target": "ES5",
    "module": "amd",
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "lib": [
      "ES6",
      "DOM",
      "ScriptHost"
    ],
    "sourceMap": true,
    "strictNullChecks": true
  },
  "include": [
    "types/**/*",
    "src/**/*"
  ]
}

Я не использую веб-пакет или что-то еще для сборки. Я просто транспилирую отдельные файлы и загружаю их через модульную систему https://github.com/SAP/openui5 (которая похожа на AMD) и собираю их только для производства.

Версия машинописного текста: 2.2.1

Надеюсь, это поможет.

Все 11 Комментарий

Это невозможно сделать, потому что в ту минуту, когда вы добавляете объявление import в исходный файл, он считается внешним модулем. По какой причине вы не используете файл определения React, в котором используется глобальный?

https://github.com/borisyankov/DefinentyTyped/blob/master/react/react-global.d.ts

Мне кажется, это решит проблему.

На самом деле я тоже пробовал react-global.d.ts , что, очевидно, помещает React в глобальное пространство, но как мне глобально переименовать его и сообщить Typescript об этом?

declare var _r = React;  // error Cannot find name 'React';

Мой реальный вариант использования - это возможность поднять модуль служебного / общего типа в глобальное пространство, чтобы мне не пришлось использовать кучу импорта относительного пути, чтобы добраться до него. Я могу сделать это в Javascript, но мне сложно дать понять компилятору Typescript, что я это сделал.

@ahejlsberg - Я уверен, что у вас есть

Например, вы можете создать файл декларации r.d.ts :

/// <reference path="react-global.d.ts"/>
declare var R: typeof React;

а затем просто ссылаться на этот файл везде. Или даже лучше:

/// <reference path="react-global.d.ts"/>
import R = React;

что позволит вам также ссылаться на типы из React как R.xxx.

Я никогда раньше не видел использования typeof - довольно круто. Это отлично работает для уже определенных модулей из .d.ts , но я до сих пор не вижу способа поднять внешний модуль, определенный в Typescript, в глобальное пространство и сообщить Typescript об этом. Может быть, потому что это антипаттерн, и мне нужно просто преодолеть это ...

У нас было несколько запросов (например, # 2357) о расширении typeof для поддержки внешних модулей, но пока особого спроса на эту функцию не было.

Вообще говоря, программы пишутся либо без внешних модулей, либо исключительно с внешними модулями. За исключением начальной части приложения для браузера AMD, действительно нет среды выполнения, в которой даже возможна смешанная модель. Так что да, это в основном антипаттерн.

Спасибо, что уделили мне время, чтобы подшутить над этим! Я только начал изучать внешние модули (чтобы поиграть с будущими фреймворками Angular2 и Aurelia). Такие вопросы, как # 17, # 2338 и # 2839, в конечном итоге кажутся мне больше из того, что я ищу. Надеюсь, я получу более четкую обратную связь, когда углублюсь в свой текущий проект.

Это все еще невозможно? Я пытаюсь использовать TypeScript с VueJS, и я был бы очень признателен, если бы мог импортировать несколько вещей в глобальное пространство имен, чтобы все компоненты могли использовать его без необходимости импортировать эти вещи. Были ли достигнуты какие-либо успехи или какие-то хитрости, чтобы заставить эту работу работать?

@Evertt

Я нашел способ, который, по-видимому, работает с машинописным текстом 2.xx В моем случае я хочу выставить библиотеку ramda как глобальную R .

  1. npm install ramda @types/ramda
  2. создать файл typings/ramda.d.ts
  3. добавьте вновь созданную папку typings в файлы include в .tsconfig.json:
"include": [
    "typings/**/*",
     ...
]
  1. добавить магию в typings/ramda.d.ts :
import * as _R from 'ramda';

export as namespace R;
export = _R; 

Теперь все файлы ts в моем проекте предполагают, что есть типизированный глобальный R я не выполняю никаких дополнительных операций импорта или чего-то еще в этих файлах.

@geekflyer, когда я пытаюсь сделать это, используя следующий код в моем types/vue.d.ts :

import * as V from 'vue'

export as namespace Vue
export = V

Я получаю следующую ошибку всякий раз, когда пытаюсь использовать где-нибудь глобальный Vue :

error TS2686: 'Vue' refers to a UMD global, but the current file is a module. Consider adding an import instead.

Вы тоже когда-нибудь получали эту ошибку? Если да, то что вы с этим сделали?

редактировать

Если вы не получаете эту ошибку и не знаете, почему я получаю эту ошибку, возможно, вы захотите показать мне весь файл tsconfig.json и, возможно, даже конфигурацию веб-пакета?

Привет, @Evertt, действительно, я тоже получаю эту ошибку. Изначально в моем исходном коде не использовался синтаксис модуля ES6, но как только я переделал некоторые файлы в соответствии с этим синтаксисом, я получил ту же ошибку. Провел небольшое исследование, и то, что сработало для меня сейчас, - это когда я создаю второй файл globals.d.ts и помещаю его также в папку typings:

import * as _R from 'ramda';
import * as _mobx from 'mobx';

declare global {
  const R: typeof _R;
  const mobx: typeof _mobx;
}

Фактически, один только этот файл, кажется, "удовлетворяет" компилятор машинописного текста, поэтому теоретически вам не понадобятся другие файлы, о которых я упоминал ранее. Однако в моем конкретном случае (я использую WebStorm), когда у меня был только файл globals.d.ts, моя IDE постоянно проверяла меня, чтобы импортировать модули, а также завершение этих глобальных объектов было неполным. Итак, я в основном сохранил оба файла в каталоге typings, который соответствует машинописному тексту и моей IDE. Не очень хорошо, но для тех немногих глобалов, которые обычно используются, я думаю, что эти файлы можно поддерживать.

Это мой tsconfig.json для справки:

{
  "compilerOptions": {
    "target": "ES5",
    "module": "amd",
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "lib": [
      "ES6",
      "DOM",
      "ScriptHost"
    ],
    "sourceMap": true,
    "strictNullChecks": true
  },
  "include": [
    "types/**/*",
    "src/**/*"
  ]
}

Я не использую веб-пакет или что-то еще для сборки. Я просто транспилирую отдельные файлы и загружаю их через модульную систему https://github.com/SAP/openui5 (которая похожа на AMD) и собираю их только для производства.

Версия машинописного текста: 2.2.1

Надеюсь, это поможет.

@geekflyer спасибо, что были очень полезны

Была ли эта страница полезной?
0 / 5 - 0 рейтинги