Установите несколько определений типов машинописного текста, объявляющих одну и ту же глобальную переменную

Я создаю приложение, используя машинописный текст, узел и электрон.

Я использую jquery в приложении и установил пакет @ types / jquery, чтобы иметь подсказки intellisense.

Затем я создал тест с использованием мокко и спектрона. Spectron использует webdriverio и предоставляет свой API через некоторые свойства. Мне нужно использовать эти свойства, поэтому я установил @ types / webdriverio, чтобы иметь подсказки intellisense.

Теперь, когда я запускаю инструмент tsc для компиляции проекта, я получаю следующие ошибки:

node_modules/@types/jquery/index.d.ts(36,15): error TS2451: Cannot redeclare block-scoped variable '$'.
node_modules/@types/webdriverio/index.d.ts(1898,18): error TS2451: Cannot redeclare block-scoped variable '$'.
node_modules/@types/webdriverio/index.d.ts(1899,18): error TS2451: Cannot redeclare block-scoped variable '$'.

Проблема в том, что оба пакета объявляют глобальную переменную $. Вы также можете проверить это на их страницах npm в разделе «Глобальные значения»:

https://www.npmjs.com/package/@types/jquery

https://www.npmjs.com/package/@types/webdriverio

Я не понимаю, почему tsc пытается скомпилировать их вместе, если я не использую jquery и webdriverio в одном и том же файле .ts?

Кроме того, даже если я закомментирую тест, поэтому я не буду ссылаться на webdriverio в любом месте, когда я запускаю tsc, я получаю те же ошибки. Вероятно, tsc компилирует все исходники в node_modules / @ types вместе. Фактически, если я удалю папку node_modules / @ types / webdriverio и снова запущу tsc, я не получу ошибки (конечно, пока я буду комментировать тестовый код).

Это мой tsconfig.json, который находится в корне проекта:

{
    "compilerOptions": {
        "target": "ES6",
        "module": "commonjs",
        "sourceMap": false,
        "inlineSourceMap": true,
        "inlineSources": true,
        "declaration": false,
        "outDir": "dist"
    },
    "include": [
        "src/**/*"
    ]
}

Весь мой исходный код находится в каталоге src. Тесты находятся в src / test.

Могу ли я сделать какую-либо конфигурацию, чтобы во время компиляции типы webdriverio и jquery были разделены? Кроме того, я видел несколько примеров кода, написанных на js, где они используются вместе: это невозможно в машинописном тексте?


person Mic    schedule 11.03.2018    source источник


Ответы (1)


Прошло много времени, но я нашел решение!

Вам нужно определить два отдельных tsconfig: один для основного проекта и один для тестов.

tsconfig.project.json

{
    "compilerOptions": {
        "target": "ES6",
        "module": "commonjs",
        "sourceMap": false,
        "inlineSourceMap": true,
        "inlineSources": true,
        "watch": false,
        "declaration": false,
        "outDir": "dist",
        "typeRoots": ["./typings"],
    },
    "include": [
        "src/**/*"
    ],
    "exclude": [
        "src/test/*"
    ]
}

tsconfig.test.json

{
    "compilerOptions": {
        "target": "ES6",
        "module": "commonjs",
        "sourceMap": false,
        "inlineSourceMap": true,
        "inlineSources": true,
        "watch": false,
        "declaration": false,
        "outDir": "dist",
        "typeRoots": ["./typings"],
    },
    "include": [
        "src/test/*"
    ]
}

Затем в файле package.json определите два разных сценария для запуска tsc для двух только что определенных вами tsconfig:

{
...
  "scripts": {
    "test": "tsc -p tsconfig.test.json && mocha --exit dist/test",
    "tsc": "tsc -p tsconfig.project.json",
    ...
  },
...
}

Ключевым моментом является конфигурация typeRoots, которая перезаписывает поведение компилятора машинописного текста по умолчанию. По умолчанию загружается каждый пакет, определенный ниже любой папки @types (таким образом, включаются все @types, установленные в папке node_modules). При перезаписи этой конфигурации @types в node_modules включаются только при наличии ссылки. В качестве альтернативы вы можете заменить конфигурацию typeRoots на

"types": []

Из https://www.typescriptlang.org/docs/handbook/tsconfig-json.html

@types, typeКорни и типы

По умолчанию все видимые пакеты «@types» включены в вашу компиляцию. Пакеты в типах node_modules / @ любой включающей папки считаются видимыми; в частности, это означает пакеты внутри ./node_modules/@types/, ../node_modules/@types/, ../../node_modules/@types/ и так далее.

Если указан typeRoots, будут включены только пакеты с typeRoots.

...

Укажите «типы»: [], чтобы отключить автоматическое включение пакетов @types.

Помните, что автоматическое включение важно только в том случае, если вы используете файлы с глобальными объявлениями (в отличие от файлов, объявленных как модули). Если вы, например, используете оператор import "foo", TypeScript может по-прежнему просматривать папки node_modules и node_modules / @ types, чтобы найти пакет foo.

Еще один важный момент - разделить файлы конфигурации. Таким образом вы можете исключить тестовые файлы при компиляции основного проекта и наоборот. Это важно, потому что основной проект включает jquery, а тестовые файлы включают webdriverio. Скомпилировав их вместе, вы получите те же ошибки, которые описаны в вопросе.

person Mic    schedule 20.01.2019