Typescript: Поддержка поиска модулей в node_modules при импорте.

Созданный на 25 июл. 2014  ·  138Комментарии  ·  Источник: microsoft/TypeScript

Обновление 5 ноября 2015 г.

Функциональность, запрошенная ниже, в настоящее время реализована в машинописном тексте, по крайней мере, с 1.8 с одним основным отличием:

Вместо свойств typescript.main и typescript.definition имеется только одно свойство typings , которое можно указать либо на файл d.ts , либо на обычный файл .ts файл.

Если вы разрабатываете модуль только для локального использования, вы можете указать $# typings .ts файл .ts, но если вы планируете опубликовать модуль, рекомендуется, чтобы он указывал на файл d.ts . Это связано с тем, что вы не хотите, чтобы ваши потребители модулей перекомпилировали ваши файлы модулей, а просто потребляли их типизацию.

Я установил пример использования этого здесь:
https://github.com/chanon/typescript_module_example

Здесь есть страница документации, которая содержит дополнительную информацию:
http://www.typescriptlang.org/docs/handbook/typings-for-npm-packages.html

Спасибо разработчикам TypeScript и всем участникам.

Исходная проблема / запрос функции следует


Мотивация

В TypeScript намного сложнее повторно использовать модули typescript по сравнению с повторным использованием модулей npm в JavaScript.

Было бы полезно, если бы компилятор машинописного текста был достаточно умен, чтобы искать в папках node_modules и файлах package.json.

Причина в том, что разработчики модулей npm, использующие TypeScript, могут начать писать и распространять модули через сам npm. TypeScript сможет использовать инфраструктуру npm и широкую поддержку.

Пример для node_modules

Если бы у нас было:

./node_modules/concator/index.ts
./myApp.ts

А в index.ts у нас было:

export function concat(param1: string, param2:string): string {
      return param1 + ' ' + param2;
}

в myApp.ts:

import concator = require('concator');  // loads the module from node_modules
var result = concator.concat('I like', 'this.');
var wontWork = concator.concat('this will fail');  // compile error, concat needs 2 params

Таким образом, компилятор достаточно умен, чтобы найти модуль в node_modules, и он автоматически использует версию машинописного текста (index.ts).

Затем, когда код компилируется в JavaScript, он, естественно, использует версию JavaScript.

Импорт папок как модулей

Более простой случай — поддержка популярного правила Node.js http://nodejs.org/api/modules.html#modules_folders_as_modules , предложенного @vvakame ниже и в закрытой (полудублированной) проблеме № 207.

typescript.main в package.json

В файлы package.json может быть добавлено, чтобы указать, где находится основной файл .ts модуля TypeScript npm. Это было бы похоже на ключ main , который указывает, где находится основной файл JavaScript/.js, но вместо этого для TypeScript.

Например, package.json для модуля npm с именем «myModule», расположенного по адресу node_modules/myModule/package.json

{
     "main": "./dist/index.js",
     "typescript": {
          "main": "./src/index.ts"
     }
}

В этом примере node_modules/myModule/src/index.ts будет основным файлом TypeScript, а выполнение import myModule = require("myModule"); приведет к импорту файла node_modules/myModule/src/index.ts .

Для кодировщика JavaScript, пишущего var myModule = require("myModule"); в файле JavaScript, требование загрузит файл node_modules/myModule/dist/index.js как обычно.

Как видно из этого примера, TypeScript src находится в папке node_modules/module-name/src , а скомпилированные JS-файлы — в node_modules/module-name/dist .

Нечто подобное может быть (полу) стандартом для модулей TypeScript npm, чтобы исходный код TypeScript был четко отделен от скомпилированного вывода JavaScript.

Более простой случай, предложенный @vvakame ниже, — это поддержка популярного правила Node.js http://nodejs.org/api/modules.html#modules_folders_as_module .

typescript.definition в package.json

Другой возможный ключ для package.json для модулей npm, отличных от TypeScript (обычный JavaScript), может быть typescript.definition . Это указывает на файл .d.ts, определяющий модуль для пользователей TypeScript модуля npm.

Так что
import $ = require('jquery');
автоматически прочитает файл jquery.d.ts , определенный в ключе typescript.definition в jQuery package.json, и сделает $ правильным типом.

Пример формата:

{
     "main": "./dist/index.js",
     "typescript": {
          "definition": "./index.d.ts"
     }
}

(Этот формат уже используется tsd, как объясняет @Bartvds ниже.)

Тогда нам, кодерам TypeScript, нужно будет просто попытаться привлечь как можно больше сопровождающих модулей npm, не использующих TypeScript, для слияния наших запросов на вытягивание, содержащих наши файлы .d.ts и ключи package.json typescript.definition .

Если нам это удастся, то жизнь программистов на TypeScript будет счастливой... больше не будет отдельного управления файлами DefinitelyTyped .d.ts. Просто установите npm, и вы также получите свои определения TypeScript! Автоматически и в соответствии с установленной версией модуля.

Список преимуществ

Что мы получаем от всего этого

  • Модули npm можно писать на TypeScript.
  • Эти модули могут использовать программисты как TypeScript, так и JavaScript.
  • Пользователи модуля, использующие TypeScript, получают преимущества статической типизации без необходимости кодировщику модуля (или пользователю) использовать обычный метод записи (или создания) отдельных файлов .d.ts (поэтому, когда исходный код модуля уже находится в TypeScript нам не нужно поддерживать еще один файл .d.ts)
  • Был бы способ легко повторно использовать и распространять модули TypeScript с помощью npm, с которым все уже знакомы.
  • Это могло бы способствовать продвижению самого использования TypeScript, поскольку кодеры JavaScript, использующие модули npm, написанные на TypeScript, могут увидеть, насколько хорош/лучше исходный код TypeScript, и попытаться переключиться на него. Или они могут захотеть внести свой вклад в модуль, и, поскольку исходный код находится на TypeScript, им придется изучить его, что может привести к тому, что он им понравится и они решат использовать его в своих собственных проектах.
  • По сути, это помогло бы расширить сообщество TypeScript благодаря возможному совместному использованию кода. Прямо сейчас у каждого код TypeScript в основном свой собственный / в своем собственном бункере. На самом деле это, вероятно, чрезвычайно важная вещь, поскольку отсутствие правильного/простого способа совместного использования/распространения/повторного использования модулей, вероятно, ограничивает рост языка. [1]
  • Повторное использование модулей во внутренних проектах было бы намного проще и уменьшило бы потребность во всех этих относительных путях к файлам .d.ts и относительных путях в модулях, а также в общих вещах .d.ts. (Прямо сейчас, когда я пишу код на TypeScript, я считаю, что мне нужно научиться хорошо считать ../../ s)
  • Этот подход также поддерживает Browserify/Webpack, так как Browserify/Webpack также смотрит в node_modules, поэтому это позволяет легко повторно использовать/распределенные npm модули TypeScript как для сервера, так и для браузера.
  • Модули npm, отличные от TypeScript, можно легко использовать в TypeScript с информацией о типе с помощью добавления ключа typescript.definition . Это позволяет упаковывать файлы определения .d.ts вместе с модулем npm, чтобы при обновлении модуля npm автоматически обновлялся его файл определения .d.ts. Это устраняет необходимость вручную обновлять файлы .d.ts.
  • Использование файлов определений через typescript.definition проще, потому что это просто оператор import moduleName = require("moduleName") без необходимости в отдельном операторе ///<reference ...
  • Использование файлов определений через typescript.definition также должно позволять использовать разные версии модуля в одной кодовой базе без конфликтов имен типов.

Подробное предложение

@ Nemo157 написал очень подробное предложение о том, как все это должно работать:

Предлагаемый TypeScript требует семантики разрешения
https://gist.github.com/Nemo157/f20064a282ee620f3877

Дополнением к предложению является использование папок /typings , которые могут содержать файлы определений, которыми можно автоматически управлять с помощью таких инструментов, как tsd для модулей JavaScript npm, которые не будут включать файлы определений в свои репозитории. .

Заключительные подтверждающие факты

Поскольку TypeScript компилируется в JavaScript, который работает в основном в двух местах: node.js и в браузерах, поддержка node_modules выгодна в обоих местах (практически везде, где используется TypeScript) из-за npm и Browserify/Webpack.

т.е. нет причин придумывать другую схему, когда node_modules — это то, что все пользователи TypeScript уже используют, возможно, для 75%-100% всего их кода JavaScript. (Вычет 25% возможно пользователям RequireJS.)

Сноски

[1] - Кстати, я вижу, что есть менеджер пакетов NuGet (?) от Microsoft, который может распространять модули машинописного текста (?), но исходя из фона, ориентированного на node.js (не ориентированного на .NET), я не вижу, чтобы NuGet стал широко используется за пределами магазинов, ориентированных на Microsoft, тем более что npm является _the_ стандартом для node.js, а также ведущим стандартом для клиентского JavaScript. Если бы я не использовал TypeScript, я бы никогда не услышал о NuGet. Среднестатистический кодировщик JavaScript на node.js/клиентской стороне, вероятно, предпочтет использовать npm, тот же инструмент, который они уже используют, вместо того, чтобы использовать что-то специфичное для Microsoft, например NuGet. (На самом деле я ничего не знаю о NuGet, поэтому то, что я здесь говорю, может на самом деле не иметь значения.)

Committed Suggestion

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

В любом случае, сейчас компилятор утверждает, что не может найти модуль, хотя на самом деле он просто отказывается импортировать модуль без определения типа. Это не очень полезно, не так ли?

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

[перемещено в typescript.main в package.json в описании проблемы выше]

:+1:
Я думаю, что http://nodejs.org/api/modules.html#modules_folders_as_modules — очень популярное правило Node.js.

другой пример.

./тест/index.ts

export function hello() { return "Hello, world"; }

./main.ts

import test = require("./test/");
console.log(test.hello()); // print "Hello, world"

[перемещено в typescript.definition в package.json в описании проблемы выше]

Одним из решений было бы решить эту проблему с помощью более качественных инструментов. Например, import foo = require('foo') дает вам подсказку для поиска некоторого локального node_module+package.json (foo — это проект ts) или определение DT (foo — это проект js, где авторы библиотеки не хотят поддерживать ts def) .

к вашему сведению; На самом деле я тестирую что-то подобное в TSD; способ предоставления и связывания определений, которые входят в пакеты npm (или bower).

Он есть в моей версии dev для 0.6 и работает путем добавления элемента typescript в package.json (или bower.json) с подэлементом definition (подэлемент, потому что, возможно, один день тоже будет source или что-то в этом роде).

{
    ...
    "main": "./index.js",
    "typescript": {
        "definition": "./foo.d.ts"
    }
    ...
},

Затем вы можете запустить команду на TSD, в настоящее время tsd link , и она просканирует все файлы package.json в node_modules (или Bower или что-то еще), найдет это свойство, если оно определено, и добавит ссылку на него в центральный tsd.d.ts Пакет

Пример: определено здесь и используется здесь

@Bartvds Это довольно мило. Это может быть первым шагом к добавлению .d.ts в пакеты npm. Мне нравится структура package.json с «определением» в «машинописном тексте», она намного более организована.

Если бы сам компилятор TypeScript мог читать его автоматически, было бы очень круто.

Пометка для обсуждения — более разумное разрешение внешнего модуля — это то, о чем нам нужно поговорить, чтобы понять различные сценарии здесь. Это обсуждалось ранее, и мы внесли несколько изменений в 1.0.

Также обсудите # 207 — поиск в «индексе»

:+1:

@chanon tsMain не нужен, если мы используем генерацию объявлений.

Да, эта проблема чрезвычайно важна даже для браузеров — многие проекты используют браузеры/упаковки и, следовательно, макеты каталогов, совместимые с узлами.

:+1:

В репозитории codeplex уже была проделана некоторая работа в этой области, один запрос на включение от leebyron и один от kayahr .

Я хотел попробовать перенести один из них в новый репозиторий, но, похоже, связанный с ним код был сильно переработан.

Я написал предложение о том, как добавить это в компилятор TypeScript . Это также включает поиск в каталоге typings , так как это будет важно при работе с модулями javascript, которые не будут поддерживать свои собственные определения typescript. К сожалению, для того, чтобы все это работало прозрачно с помощью tsd , все равно потребуется немного потрудиться, поскольку требование, чтобы файлы /// <reference d были внешними объявлениями окружения, делает вещи немного запутанными. Я рассмотрю реализацию этого в ветке и предоставлю несколько примеров модулей, использующих его.

Выглядит разумно. Будет ли это охватывать модули с конфликтующими зависимостями типов? Я имею в виду, если приложение импортирует A и B, а B также зависит от A. Легко попасть в ошибки повторяющихся типов, если есть две копии внешних объявлений.

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

Это одна из основных проблем с текущими определениями tsd , которую он пытается решить, определяя внешние модули окружения, и они не могут справиться с несколькими версиями библиотеки с одинаковыми именами, но немного разными типами. .

@joewood также будут проблемы между разными версиями A

├── [email protected]
└── [email protected]
    └── [email protected]

у них нет способа справиться с несколькими версиями библиотеки с одинаковыми именами, но немного разными типами.

интересно услышать решения того же самого. TypeScript имеет область переменных уровня global для внешних объявлений.

Даже если версии совпадают, на данный момент я вижу проблемы с двумя разными, но совпадающими файлами объявлений окружения, что приводит к ошибкам дублирования символов. Локально определенная директива /// reference должна каким-то образом вернуться к одному файлу. Либо это, либо идентификатор типа должен включать путь, а структурная типизация позаботится о несоответствии версий и т. д.

@joewood Да, это то, что я надеюсь, будет исправлено в большинстве случаев путем изменения require для загрузки правильных определений, по возможности избегая /// reference . Внешние модули будут идентифицированы по их абсолютным путям вместо внешних объявлений, поэтому должна быть возможна загрузка нескольких модулей с одним и тем же именем с разных путей и в разных версиях.

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

:+1:

:+1: Спасибо @Nemo157 и всем за обсуждение.

Я обновил текст главной проблемы, объединив дополнения package.json и связав их с предложением @Nemo157 .

:+1:

Я сделал первоначальную реализацию своего предложения, а также создал набор примеров модулей, чтобы показать, что все различные способы создания модуля будут работать. В том числе использование разных версий одной и той же библиотеки в разных подмодулях.

:+1:

Папки как модули с index.ts :+1:

:+1:

:+1:

:+1:

:+1:

:+1: :+1: :+1:

:+1: :+1: :+1: :+1:

Комментарий, чтобы вернуть это на наш радар.

У меня был хороший успех с предложением @Bartvds :

Затем вы можете запустить команду на TSD, в настоящее время ссылка tsd, и она просканирует все файлы package.json в node_modules (или Bower или что-то еще), найдет это свойство, если оно определено, и добавит ссылку на него в центральный пакет tsd.d.ts в вашем проекте.

Так что определенно рассмотрите возможность поддержки typescript в package.json , так как это путь сообщества.

Нам определенно нужно, чтобы tsc знал о папке node_modules , если TypeScript будет широко использоваться в сообществе node.js. В настоящее время я использую символические ссылки на модули, которые являются частью моего проекта разработки (используя npm-workspace), и на данный момент у меня есть два варианта:

  • импортировать напрямую из node_modules, что выглядит неправильно: import Foo = require("node_modules/mymodule/Foo");
  • получить tsc для создания файлов объявлений, а затем сшить их вместе, используя поддерживаемый вручную файл объявления модуля, который переключает строковые имена модулей

Может ли tsc проверить имя внешнего модуля в объявлениях импорта, а затем во время разрешения пути также применить node_modules так же, как это делает среда выполнения node.js? Параметр компилятора также может включать или выключать это.

:+1: :+1: :+1:

Может ли tsc проверить имя внешнего модуля в объявлениях импорта, а затем во время разрешения пути также применить node_modules таким же образом, как это делает среда выполнения node.js

Вот как это _должно_ быть. Текущий способ простого просмотра дерева каталогов для поиска файла с указанным именем не имеет ничего общего с контекстами выполнения JS.

Это было в моем списке некоторое время теперь. постараюсь получить это в следующем релизе.

Мы ( Booktrack ) используем TypeScript для всех наших веб-разработок, и мы сталкиваемся с теми же проблемами, что и разработчики node.js. Я высказываюсь, потому что голос веб-разработчиков не кажется таким громким, как голос разработчиков узлов.

Решения (в порядке от наихудшего к лучшему для нас):

  1. разрешение имен внешних модулей верхнего уровня с помощью жестко закодированного поиска в node_modules
  2. нет контроля над разрешением имен внешних модулей верхнего уровня
  3. флаг компилятора для управления необязательным разрешением имен внешних модулей верхнего уровня в каталог node_modules
  4. параметр компилятора «путь (и) поиска модуля» для управления необязательным разрешением имен внешних модулей верхнего уровня в заданный путь (пути)
  5. параметр "преобразователь модуля" компилятора, чтобы предоставить компилятору плагин JS, который будет разрешать все имена внешних модулей (не только верхнего уровня).
  6. соответствующие подключения к языковым службам, чтобы можно было контролировать разрешение имен внешних модулей.

Вариант 1 ужасен, я бы предпочел вариант 2.

Варианты 5 и 6 допускают экзотическое использование операторов импорта, например, при работе с плагинами requirejs или webpack. Основная идея: компилятор делегирует все поиски имени внешнего модуля (не только верхнего уровня) третьей стороне (плагину или обратному вызову). Делегат, получив путь к компилируемому модулю и имя внешнего модуля, возвращает компилятору путь к файловой системе ИЛИ информацию о типе для данного имени модуля.

Я был бы счастлив, если бы был реализован вариант 4, рад, если бы был реализован вариант 6, и был бы счастлив, если бы были реализованы и вариант 4, и вариант 6.

Как насчет --basePath для вашего корня поиска модулей, все импорты модулей будут просматриваться относительно этого пути. Это относится только к AMD.

Я думаю, что проблема с узлом намного проще, нам просто нужно его внедрить :)

Обратите внимание, что на самом деле мы давно получили реализацию (и тесты) от @Nemo157 https://github.com/Microsoft/TypeScript/issues/247#issuecomment -57422329.

Согласитесь с @mark-buer и @mhegazy , вариант 4 путь поиска должен быть простым решением. Определенно требуется более продуманное решение в языковой службе (вариант 6) в долгосрочной перспективе.

_Стоит добавить_: это само по себе не решит проблему повторного использования TypeScript в npm из-за проблемы с повторяющимся символом для общих ссылок на типы #1125. Нам действительно нужно избегать ///с помощью файлов .tsconfig и правильно исправьте это, объединив пакеты в один внешний типизированный модуль, как это предлагается в # 17.

Еще один голос за то, чтобы папка node_modules распознавалась компилятором машинописного текста.

Для модулей CommonJS машинописный текст в идеале должен следовать тому же разрешению имен файлов, что и require.resolve (как указано в псевдокоде на этой странице: http://nodejs.org/api/modules.html#modules_all_together.

эта функциональность имеет решающее значение для интеграции компилятора машинописного текста в другие упаковщики узлов, такие как browserify. Патч @ Nemo157 отлично справляется со своей задачей, но он не позволяет легко тестировать существующие упаковщики, поскольку большинство из них перешли на более поздние версии машинописного текста и больше не совместимы с его кодом.

Где каталог node_modules должен быть относительно источников?

Atom-TypeScript теперь поддерживает typescript.definition из коробки. Подробности: https://github.com/Microsoft/TypeScript/issues/2829 .

Вы также можете легко создавать такие пакеты с помощью atom-typescript :rose: снова см. # 2829

Ограничение

Это будет работать _безукоризненно_, если вы поделитесь пакетом, который не зависит ни от каких внешних библиотек. Если да, то нам нужен алгоритм разрешения конфликтов модулей.

Я открыт для предложений по этому делу, но мой план таков:

  • мы делаем некоторые умные вещи, читая такие d.ts , не давая TypeScript внешние комментарии reference (например, node.d.ts здесь https://github.com/TypeStrong/atom-typescript-examples /blob/master/node/node_modules/example-typescript-b/definition/sample-bdts) И вместо этого указываем на наш собственный .d.ts , если он есть в наших типизациях.

Сохранится ли это в версии 2.0? Это кажется важной функцией для внедрения Node.js, что сейчас болезненно, даже с DefinitelyTyped и ему подобными.

Это кажется важной функцией для внедрения Node.js, что сейчас болезненно, даже с DefinitelyTyped и ему подобными.

@LPGhatguy См . https://github.com/Microsoft/TypeScript/issues/2338. @vladima работает над этим, но не думаю, что это еще какая-то веха :rose:

@LPGhatguy , мы пытаемся получить это в следующем выпуске. надеюсь скоро.

@mhegazy Ты имеешь в виду 1.6? Это было бы круто!

Это связано с #2338?

да для TypeScript 1.6 (по крайней мере, это то, что мы пытаемся сделать), да для #2338; есть несколько других изменений и проблем, связанных с этим, включая # 3147 и # 4154.

Тогда почему он помечен как TypeScript 2.0 как веха?

спасибо @heycalmdown , удалил веху. мы обычно не помечаем вехи для предложений. надеюсь, у нас есть обновление в течение недели или около того по этому вопросу. быть в курсе.

Я хотел бы присоединиться к просьбе о поддержке модуля ES6, чтобы следовать этому (что, я полагаю, будет?)

Типы для

import mylib = require('mylib');
mylib.foo(mylib.bar);

должен вести себя так же, как

import { foo, bar } from 'mylib';
foo(bar);

Я хотел бы присоединиться к просьбе о поддержке модуля ES6, чтобы следовать этому (что, я полагаю, будет?

@DavidSouther Это будет _автоматически_. Поиск между ними согласован :rose:

этим занимается #4154.

Если я использую nightly, начиная с завтрашнего дня, я должен ожидать, что импорт модулей узлов будет «просто работать»?

Вопрос:
Я думаю, что это общепринятое соглашение, чтобы файлы назывались
«индекс» в commonJS и
"основной" в AMD
для коротких путей.
В вопросе сверху автор импортирует
/node_modules/concator/index.ts как
import concator = require('concator');

Пожалуйста, простите меня - в настоящее время я выясняю, поддерживается ли сейчас разрешение индекса, и как насчет index.ts или main.ts в AMD требует разрешения?
Я также пингую @basarat , чтобы узнать, будет ли он поддерживаться https://github.com/TypeStrong/atom-typescript , потому что теперь он не позволяет мне требовать каких-либо index.ts, как упоминалось выше.

@sebilasse , если вы используете typescript@next сегодня, это должно работать с --module commonjs

import concator = require('concator'); // resolves to node_modules/concator/index.ts

Нет изменений в разрешении AMD по сравнению с предыдущими выпусками.

@DavidSouther , сегодня он должен быть в typescript@next . попробуйте и дайте нам знать, как это работает.

@mhegazy @basarat :+1: хорошо. Но что вы думаете о разрешении AMD для main.ts или index.ts — не должно ли оно быть постоянным в будущем?

@sebilasse , для AMD, я думаю, нам нужно сделать что-то, как отметил @vladima в # 2338 (раздел: загрузчик модулей RequireJS/ES6).

Очень хорошо!! \о/

@mhegazy Все еще не работает так, как я ожидаю.

Я собрал https://github.com/DavidSouther/typescript-example-using-node с моим «идеальным» вариантом использования. tslib — это простая библиотека, которая экспортирует одну функцию. tsclient зависит от tslib, а также от readline из пакетов Node. Сценарий установки удобен для установки, связывания и выполнения. Я включил прогон и аннотировал неожиданные части встроенными комментариями.

% ./setup
...
> [email protected] build ~/ts-node/tslib
> tsc --version ; tsc -p src/

message TS6029: Version 1.7.0-dev.20150831
...
> [email protected] build /Users/southerd/devel/tmp/ts-node/tsclient
> tsc --version ; tsc -p src/

message TS6029: Version 1.7.0-dev.20150831
# Expect this to find tslib, but fail type checking.
# See tsclient/app.ts for details
src/app.ts(4,21): error TS2307: Cannot find module 'tslib'.

+ node ./dist/app.js # This works as expected!
What would you ask? What is the meaning of life?
42
+ set +x

Я также не получаю языковую поддержку для импорта tslib в tsclient (версия VSCode 0.7.0 (0.7.0)), хотя я не совсем уверен, какой TSC он использует или как это изменить.

Компилятор @DavidSouther TypeScript проверяет поле «typings» в package.json, чтобы найти файлы «.d.ts». С этим изменением я получаю src/app.ts(13,7): error TS2322: Type 'string' is not assignable to type 'number'. , что выглядит как допустимая ошибка.

Ах, я, должно быть, пропустил этот кусок документов. У меня все еще есть вторая проблема - как изменить версию VSCode tsc?

вы можете указать собственное местоположение TypeScript SDK для VSCode с помощью параметра "typescript.tsdk" — он должен указывать на папку, содержащую tsserver.js и стандартные файлы '.d.ts'. В случае, если TypeScript установлен как пакет npm, это будет что-то вроде

// Place your settings in this file to overwrite the default settings
{   
    "typescript.tsdk": "C:\\Sources\\bugs\\node\\typescript-example-using-node\\tslib\\node_modules\\typescript\\lib"       
}

У кого-нибудь заработал образец? Я пытался весь день играть с этим, но всегда заканчивал

error TS2307: Cannot find module

На данный момент код находится в node_modules/my-module/. И я определил index.ts, который позаботится об экспорте всего, и я сослался на него в package.json в typescript.main. В потребительском проекте я попытался импортировать {AClass} из «моего модуля»; и импортировать мой-модуль = требовать ('мой-модуль'); Оба они приводят к одной и той же ошибке с typescript 1.7.0-dev.20150901.

При разрешении модуля с не относительным именем с --module commonjs компилятор будет искать .d.ts , который соответствует имени в node_modules\name\index.d.ts , или искать в package.json для свойства typings и загрузите .d.ts, на который оно указывает.

из вашего описания похоже, что вы устанавливаете его на index.ts , вы на самом деле не хотите компилировать свои зависимости, вы просто хотите использовать их типизацию, поэтому вместо этого вы должны установить его на index.d.ts .

Я обновил шаги в алгоритме разрешения модуля узла, чтобы отразить реализацию: https://github.com/Microsoft/TypeScript/issues/2338 .

@DavidSouther , по-видимому, у меня точно такая же проблема. Когда я компилирую с зависимостью в node_modules, он не может разрешить модуль и выводит ошибку, но затем он все равно генерирует js, и если я его запускаю, он запускается. Может быть, это связано с моими настройками, я не знаю. Мой d.ts в основном пуст, у меня есть index.ts, который занимается импортом и реэкспортом всех классов моих модулей, определенных во многих файлах .ts. И затем мой файл d.ts просто ссылается на этот index.ts и экспортирует все из index.ts следующим образом:

/// <reference path="index.ts" />

declare module 'my_module' {
    export * from 'index';
}

Кроме того, он каким-то образом все еще компилирует ts из node_modules, поэтому я должен добавить чистую задачу, чтобы удалить его после компиляции. Есть ли где-нибудь описание функции, которое подытоживает процесс?

edit: я заставил его работать, но он очень хакерский и все еще выводит ошибки. Я создал d.ts с помощью dts-generator, а затем импортировал свои классы следующим образом:

import MyClass from '../../node_modules/my_module/dist/MyClass';

Если я использую импорт MyClass из 'my_module/MyClass', я компилирую его без ошибок, но во время выполнения я получаю ошибку, не могу найти модуль 'my_module/MyClass'. С приведенным выше решением он указывает непосредственно на скомпилированный .js, и во время выполнения он как-то работает, даже если он выводит ошибку, не может найти модуль во время компиляции.

Все еще возникают проблемы с импортом из подмодулей (например, npm install angular2, import { Inject, Binding } from 'angular2/di' . Сегодня вечером будет работать над получением тестового примера.

Не думайте, что angular уже связывает свои типы так, как этого ожидает компилятор TypeScript.

Вероятно, это правда; Я поработаю с ними и посмотрю, чем это закончится.

эта функция хорошо работает на typescript 1.1, например https://github.com/Nemo157/typescript_w_node_modules_example

но ошибка в машинописи 1.5.3, что-нибудь изменилось?

------ Обновить ---------

Я знаю, что выйдет в версии 1.6, спасибо

Я могу получить эту "полуработу" только в 1.6.2

Во-первых, я упаковываю библиотеку с my-lib.d.ts в каталоге dist и указываю на этот файл в атрибуте файла package.json typings (например, "typings" : "dist/my-lib.d.ts" )

Затем я импортирую эту библиотеку в файл TypeScript Test.ts , используя

import { MyObject } from "my-lib"

MyObject правильно импортирован, а код js генерируется при транспиляции.
Код Visual Studio даже обеспечивает завершение на MyObject

Однако я получаю предупреждения компилятора о том, что:
Test.ts(10,60): error TS2306: File '[]/node_modules/my-lib/dist/my-lib.d.ts' is not a module.

Код Visual Studio фактически покажет импорт как серьезную ошибку

Любые импортированные модули из пакета узлов должны быть «внешними модулями», а не «объявлениями внешних модулей». т.е. нет объявлений declare module "foo" {.. } , а есть объявления импорта или экспорта верхнего уровня в файле.

Поэтому, если ваш пакет «my-lib» написан на машинописном языке, просто создайте его с помощью --declarations и установите типизацию в файл .d.ts вашего основного модуля. если нет, и ваши типизации являются чем-то, что вы создали вручную или получили от определенно типизированного, тогда вам нужно будет либо изменить его на внешний модуль, либо подождать, пока # 4665 не будет разрешен (надеюсь, скоро).

Причина этого ограничения в том, что это может впоследствии привести к загрязнению глобальной области видимости и конфликтам для пользователей вашего пакета. об этом есть долгая дискуссия в # 4665.

Вот некоторая документация для будущих поисков: https://github.com/Microsoft/TypeScript/wiki/Typings-for-npm-packages .

@mhegazy Спасибо за ваш быстрый ответ, который действительно помог мне в моем стремлении автоматизировать сборку библиотек commonjs, написанных на Typescript, которые могут использоваться как кодом Javascript, так и кодом TypeScript.
Синтаксис и разрешение import/export в последнее время развиваются так быстро, что, как мне кажется, сейчас не хватает подробного руководства о том, как его создать.

У меня это работает... с одной оговоркой (и, следовательно, еще один вопрос)

Вот упрощенный вид установки.

Библиотека состоит из трех объектов A1, A2 и B в двух машинописных файлах A.ts и B.ts; что-то типа

источники

A.ts

class A1{}
class A2{}
export { A1, A2 }

B.ts

class B{}
export { B }

То, что мы хотим показать, собрано в index.ts :

export * from './A'
export * from './B'

строить
Сборка ведется с помощью grunt и установлены флаги --module commonjs и --declaration на tsc 1.6.2
Конечным результатом сборки является дерево, имеющее вид

    package.json
    dist/
        js/
             A.js
             B.js
             index.js
        typings/
             A.d.ts
             B.d.ts
             index.d.ts

package.json содержит эти две записи:

"main": "dist/js/index.js",
"typings": "dist/typings/index.d.ts"

Использование этой библиотеки в TypeScript 1.6.2 с простым import {A1, A2, B} from "mylib" работает абсолютно нормально. Многоуровневые зависимости (т.е. библиотеки, импортирующие друг друга) тоже прекрасно работают.

Проблемы возникают, когда библиотека зависит от другой библиотеки, которая _не_ является библиотекой TypeScript.
Скажем, библиотека зависит от Node.js.
В одном из исходных файлов будет ссылка на типизацию NodeJS, например
///<reference path="../typings/node/node.d.ts"/>

После транспиляции эта инструкция <reference > окажется в соответствующем файле объявлений; проблема в том, что путь к node.d.ts скорее всего неправильный или не существует.
Есть ли рекомендуемый способ сделать это?

_Примечание_: эта проблема решается использованием файла index.ts для демонстрации интересных частей библиотеки, поскольку в файле index.ts нет причин содержать инструкцию <reference > , а в версии 1.6 .2 компилятор, кажется, не заботится о том, что Adts имеет неверный путь в справочной инструкции

@bgrieder Мы обрабатываем это в Phosphor, используя tsconfig.json :
https://github.com/фосфорджс/фосфор-виджет/блоб/мастер/src/tsconfig.json

Мы просто добавляем любые внешние типы, которые нам нужны, в скомпилированные файлы. Это означает, что если какой-либо из этих внешних типов является частью нашего общедоступного интерфейса, потребители кода также должны будут предоставить эти внешние типы как часть своей сборки. _Это хорошо_. Если бы мы объединили эти определения, а какая-то другая библиотека, используемая потребителем, _также_ объединила те же самые определения, возникли бы конфликты повторяющихся символов.

@sccolbert Да!
Я беспокоился, что удаление инструкций <reference ...> нарушит автодополнение во всех IDE, но нет: по крайней мере Visual Studio Code 0.8.0 кажется достаточно умным, чтобы выбрать эти определения из tsconfig.json файл! (после перезагрузки)

Готово с reference . Отлично !

@sccolbert

Что, если вы используете в нем простой проект Node.js и *.d.ts для него, как вам поможет решение tsconfig ?

@heycalmdown вы просто добавляете d.ts в поле files в tsconfig , вот пример, который делает это:

https://github.com/фосфорджс/фосфор-виджет/блоб/мастер/тест/src/tsconfig.json#L11
https://github.com/фосфорджс/фосфор-виджет/блоб/мастер/тест/src/index.ts#L10

Обратите внимание, что мы должны использовать здесь require вместо import только из-за того, как файл d.ts для expect.js записывается внутри.

Хорошо, я понял. Ваши репозитории выглядят как хороший пример.

Действительно ли это было реализовано в TypeScript 1.6.2?

Если да, может ли кто-нибудь сказать мне, что я здесь делаю неправильно?:
https://github.com/chanon/typescript_module_example

Вероятно, вам нужен синтаксис импорта es6.

В среду, 4 ноября 2015 г., 6:10 утра [email protected] написал:

Действительно ли это было реализовано в TypeScript 1.6.2?

Если это так, может ли кто-нибудь сказать мне, что я здесь делаю неправильно?:
https://github.com/chanon/typescript_module_example


Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/Microsoft/TypeScript/issues/247#issuecomment-153688004
.

Я только что обновил его, чтобы использовать синтаксис импорта es6, но все равно получаю те же ошибки (не могу найти модуль).

@chanon package.json для пакетов node_modules должен иметь ключ typings , который указывает на файл d.ts , а _не_ ключ typescript , указывающий .ts файлов, как у вас сейчас.

Мы используем разрешение узловых модулей исключительно в PhosphorJS (на TS 1.6.2), и все работает нормально. Вот пример: https://github.com/фосфорджс/фосфор-виджет/блоб/f908341cb1d46ada8ad8149e695a75e7ea2fde57/package.json#L6

Спасибо @sccolbert , однако мое первоначальное предложение (в начале этой проблемы) состояло в том, чтобы разрешить свойство typescript.main в package.json , которое указывало бы на основную точку входа TypeScript для написанных пакетов модулей узлов. в типскрипте.

Это позволило бы импортировать модули TypeScript в код TypeScript без необходимости в файлах ввода d.ts (их не нужно было бы даже генерировать).

@chanon Я просто указал, что вам нужно сделать, чтобы ваш код заработал.

@sccolbert Я вижу, спасибо.

Может ли кто-нибудь, кто знает, сказать мне, должен ли я создать еще одну проблему, запрашивающую эту конкретную функцию?

Основные проблемы, связанные с логикой разрешения модуля (кроме этой), по-видимому, # 2338, которая закрыта, и # 5039, которая, похоже, связана с поддержкой разрешения пути в стиле SystemJS, что выглядит очень сложным.

Однако простой импорт в стиле CommonJS, как изначально требовалось в этом выпуске, кажется, был забыт? По крайней мере, часть о typescript.main и папках в качестве модулей?

Я не понимаю необходимости (и желания иметь) файлы d.ts, если и модуль, и потребитель модуля уже написаны на TypeScript.

На самом деле это не сильно отличается от импорта файла TypeScript относительно ex.

Вместо того, чтобы делать:
import * as lib from '../relative/path/to/typescriptFile.ts'

Или:
import * as lib from '../../node_modules/myModule/index.ts'

Просто позвольте TSC найти файл машинописного текста для импорта, используя обычное разрешение пути node_modules. И, по крайней мере, разрешить импорт папок в виде модулей (с index.ts), чтобы во втором примере я мог сделать:

import * as lib from 'myModule'

Или это из-за того, что «вы на самом деле не хотите компилировать свои зависимости, вы просто хотите потреблять их типизацию»?

@chanon поведение, которое вы описываете, - это то, что сейчас находится в мастере. Вы можете попробовать typescript@next ?

исходная реализация # 2338 добавила несколько дополнительных проверок, чтобы убедиться, что это .d.ts, и это в основном по упомянутой вами причине. вы не хотите, чтобы пользователи вашего пакета компилировали ваши «исходники» при каждом вызове компилятора и получали разные выходные данные в зависимости от их параметров компилятора, вы только хотите поделиться своими типами.

Однако, если вы создаете оба пакета, вы можете сделать это, повторяя их. Ограничение было снято в #5278.

Пожалуйста, взгляните на вики-страницу для обмена наборами текста через пакет npm для получения дополнительной информации: https://github.com/Microsoft/TypeScript/wiki/Typings-for-npm-packages .

Спасибо за разъяснение @mhegazy! Я попробую.

@mhegazy Только что попробовал с typescript@next , работает как положено!

Отлично!!

И спасибо всем за участие в этом и связанных с ним вопросах :+1:

Я добавил обновление к тексту проблемы выше, чтобы объяснить, как эта функция была фактически реализована.

Рискуя наступить на минное поле, как это будет работать с обычными модулями npm, которые _не_ имеют свойство typings в package.json? Попытка использовать tape или get-parameter-names с typescript@next приводит к тому, что он взрывается у меня перед носом, поскольку он не может найти эти пакеты из-за того, что у них нет этого имущество.

Конечно, они не являются машинописными модулями, но я не могу найти обходной путь, и это блокирует значительную часть экосистемы npm.

@danpantry Обычно вы используете обычный файл .d.ts, написанный специально для этого модуля. В проекте DefinitelyTyped есть файлы .d.ts для множества общих модулей. Существует утилита tsd, которая может помочь вам установить файлы .d.ts из DefinitelyTyped и управлять ими.

Вы можете использовать обычные модули без ввода, просто используя синтаксис обычного commonjs.

например
var имя_модуля = требуется ("имя_модуля")

@chanon кажется немного хаком, чтобы использовать «классический» синтаксис require при использовании синтаксиса ES6 с TypeScript, поэтому я могу использовать зависимости JavaScript, но спасибо. Я слышал об утилите tsd, но я не уверен, как это повлияет на использование импорта ES6.. если мне не придется начать использовать /// <reference path=... для таких модулей?

Да, это один из способов. Другой способ — использовать файлы tsconfig.json и поместить корневой файл tsd.d.ts в качестве первого файла.

Вам также может быть интересно прочитать это, охватывающее tsd и типизацию https://angularclass.com/the-state-of-typescript-packages/

@joewood спасибо за информацию, последний раз, когда я изучал машинописный текст, это было во времена отдельных файлов .d.ts . отличная статья

@chanon @danpantry Несколько жаль, что import foo = require('foo') (с foo в node_modules) не работает, когда в package.json foo нет типов.

@wmono хорошо, так как, возможно, TypeScript 0.80 или, может быть, более ранний синтаксис import foo = require('foo') предназначался только для импорта модулей с типизацией. Если бы у него не было типов, вы бы использовали вместо него var foo = require('foo') . Так что я бы сказал, что это так, как есть.

@chanon Простите меня; ошибка пользователя. Похоже, что webpack боролся с «голым» require , но проблема заключалась в другом.

Извините, может кто-нибудь объяснить, почему
var foo = require('foo');
Работает для стандартного node_module без типизации, но
import foo from 'foo';
нет? Было ли это просто произвольно определено? Я не понимаю, почему последний _не должен_ работать - мне все равно, есть ли во внешней библиотеке JS типизация или нет.

Извините, может кто-нибудь объяснить, почему
var foo = требуется ('foo');
Работает для стандартного node_module без типизации, но
импортировать foo из 'foo';
нет? Было ли это просто произвольно определено? Я не понимаю, почему последнее не должно работать - мне все равно, есть ли во внешней JS-библиотеке типизация или нет.

@harangue, потому что var require был одним из конкурирующих синтаксисов модулей (этот вариант commonjs , а другие в списке включают amd ), который поддерживался _вне системы проверки типов_. Если кто-то хочет использовать систему типов, нужно сделать import require . С ES6, взявшим на себя :hammer: и заявившим, что один синтаксис (:ring:) управляет ими всеми... имеет смысл иметь этот синтаксис модуля, поддерживаемый системой проверки типов из коробки :rose:

@basarat Спасибо за разъяснение. Иконки тоже пригодились. ;) Я до сих пор не уверен, почему синтаксис ES6 требует проверки типов. Что помешает компилятору сказать: «О, я не смог найти данные о типе для этого модуля, но я все равно его импортирую». Какие побочные эффекты может вызвать это (довольно интуитивное, IMO) поведение?

Это сбивает с толку тех, кто (как и я) переходит с ES6 на TypeScript. Я ожидаю, что синтаксис импорта модуля ES6 будет вести себя так же в TypeScript, но, увы, он вообще не работает для большинства пакетов npm...

но, увы, это вообще не работает для большинства пакетов npm...

@teohhanhui я в замешательстве. Можете ли вы привести конкретный пример того, чего вы пытаетесь достичь, и каким кодом вы пытались это сделать. Это просто так, чтобы я мог быть в состоянии помочь вам :rose:

import koa from 'koa';

дает Cannot find module 'koa'. (2307) , когда target равно es6

koa (конечно) в node_modules

Однако koa не публикует типизацию Typescript в своем проекте. Это только для пакетов, которые публикуют .d.ts со своим проектом и перечисляют его в своем package.json. Поскольку koa этого не делает, вам потребуется дополнительно установить эти определения типов из Definitely Typed.

Это кажется плохим решением, так как можно было бы ожидать, что оператор import будет работать так же, как и в обычных модулях ES6. (Да, я знаю, что большинство пакетов npm являются модулями CommonJS, но их поддержка здесь все же была бы разумной.)

Я новичок в TypeScript, поэтому у меня, вероятно, неправильное понимание, но разве определения типов не являются необязательными? Почему я не могу импортировать пакет без определения типа? Я не хочу, чтобы меня заставляли искать/создавать определения типов.

Переключение на устаревший синтаксис импорта модуля TS невозможен, поскольку он запрещен при использовании цели es6 .

Я новичок в TypeScript, поэтому у меня, вероятно, неправильное понимание, но разве определения типов не являются необязательными?

Это неправильно. Определения типов _в вашем собственном коде_ могут быть неявными, что означает, что компилятор Typescript «разберется». Вы никогда не собираетесь передавать стороннюю библиотеку через компилятор Typescript, поэтому компилятор никогда не знает, что это за типы. Если вы планируете использовать сторонний код, вам действительно следует научиться использовать Definitely Typed и инструмент tsd .

Как насчет этого ответа @basarat?

http://stackoverflow.com/a/27434010/1529493

Почему модули, отличные от TypeScript, без определений типов нельзя импортировать как таковые?

Они могут: const koa = require(‘koa’)

21 января 2016 г., в 14:47, Тео Хан Хуэй ( [email protected] ) написал:

Почему нельзя импортировать модули без определений типов?


Ответьте на это письмо напрямую или просмотрите его на GitHub https://github.com/Microsoft/TypeScript/issues/247#issuecomment -173574234.

@bgrieder Я имею в виду синтаксис импорта ES6.

(то есть вы используете commonjs), если нет, используйте ответ declare var Basarat

21 января 2016 года, в 14:48, Бруно Гридер bruno. [email protected] написал:

Они могут: const koa = require(‘koa’)

21 января 2016 г. в 14:47 Тео Хан Хуэй < notifications @github.comnotifications@ github.com > написал:

Почему нельзя импортировать модули без определений типов?


Ответьте на это письмо напрямую или просмотрите его на GitHub https://github.com/Microsoft/TypeScript/issues/247#issuecomment -173574234.

Я думаю, что смысл в том, что одна из целей TypeScript состоит в том, чтобы действительный JS был действительным TS. Для синтаксиса модуля ES6 TS должен скомпилировать его с наличием объявлений типа или без них. Без объявлений типа оператор import должен просто разрешаться в any .

Я полностью согласен с этим.

@Джо Вуд 👍

21 января 2016 г., в 14:52, Joe [email protected] написал:

Я думаю, что смысл в том, что одна из целей TypeScript состоит в том, чтобы действительный JS был действительным TS. Для синтаксиса модуля ES6 TS должен скомпилировать его с наличием объявлений типа или без них. Без объявлений типов оператор импорта должен просто разрешаться в любой.

Я полностью согласен с этим.


Ответьте на это письмо напрямую или просмотрите его на GitHub https://github.com/Microsoft/TypeScript/issues/247#issuecomment -173575301.

FWIW это поведение (ожидание, что все сторонние библиотеки будут набраны заранее) - вот что заставляет меня использовать Flow поверх TypeScript. Хотя у TypeScript есть поддержка IDE, ожидать, что все будет напечатано заранее, не очень разумно, особенно когда существует множество библиотек, которые:

  • Нет на DefinitelyTyped
  • Нет папки ./typings
  • у меня нет времени печатать самому

Я предпочел бы не бороться с чем-то, что должно способствовать моему развитию.

@danpantry , почему бы просто не объявить вашу точку входа в библиотеку как любую, и компилятор удовлетворится этим:

declare var $: any;

Это обходной путь. Но я думаю, что для TypeScript было бы неплохо уважать код модуля ES6 и изящно отступать. Я не вижу веской причины, по которой оператор импорта не может вернуться к any , а не сообщать об ошибке, если модуль верхнего уровня не типизирован.

Я бы предпочел, чтобы компилятор давал сбой рано и громко (текущее поведение), а не позволял незамеченным прокрадываться проблемам во время выполнения. Я бы предпочел явно иметь строку declare var foo: any , указывающую, что «это небезопасно, и я знаю, что делаю».

Почему бы просто не разрешить синтаксис импорта ES6, когда нет доступных типизаций, проблема простого предупреждения компилятора о том, что импорт разрешен в any вместо ошибки «предотвращения эмиссии»?

21 января 2016 г., в 18:42, С. Крис Колберт ( [email protected] ) написал:

Я бы предпочел, чтобы компилятор давал сбой рано и громко (текущее поведение), а не позволял незамеченным прокрадываться проблемам во время выполнения. Я бы предпочел явно указать var foo: любую строку, указывающую «это небезопасно, и я знаю, что делаю».


Ответьте на это письмо напрямую или просмотрите его на GitHub https://github.com/Microsoft/TypeScript/issues/247#issuecomment -173649845.

В любом случае, сейчас компилятор утверждает, что не может найти модуль, хотя на самом деле он просто отказывается импортировать модуль без определения типа. Это не очень полезно, не так ли?

^^^ Это тысячу раз. Когда я впервые столкнулся с этой проблемой, не было никаких признаков того, что я делаю что-то не так. Потребовалось немало времени, чтобы разобраться в том, в чем дело (кстати, я думаю, что эта проблема — одно из немногих мест, где ее можно найти). Это так ненужно. И с Angular 2, который делает TypeScript более популярным, я могу только представить, сколько вопросов о переполнении стека возникнет из-за такого поведения.

Полностью согласен с плохим описанием обработки ошибок и просто сделайте так, чтобы он импортировался как любой!

@sccolbert Я согласен, что должно быть уведомление, но я не уверен, что это должно быть сбоем - вместо этого, возможно, предупреждение

Я согласен с @mhegazy и @sccolbert.

Я бы предпочел, чтобы наши сценарии производственной сборки (например, CI-сервер) громко жаловались, если что-то не так.

Привет, ребята,
Такое поведение просто сводит меня с ума. Файлы определений устарели или не зарегистрированы в package.json .
В конце концов, TypeScript производит JavaScript , поэтому, пока мы все не перейдем на этот язык, пожалуйста, будьте осторожны с остальным миром, который предоставляет библиотеки для родного языка на любых других транспилируемых языках, таких как ваш. .
Я действительно хочу знать, хочет ли TypeScript остаться (я бы сказал, что «интегрироваться», поскольку этого еще нет) в экосистеме JavaScript или хочет жить отдельно, как второй вариант заставит меня пойти на что-то другое.
Чтобы добиться этого, подойдет переключатель в файле .tsconfig , для этого мы можем сказать, хотим ли мы строгий импорт или нет.
Что касается громкой жалобы на CI, для этого есть тестовые фреймворки в JavaScript . В любом случае, вы не получите проверку типов во время выполнения, плохая проверка импорта является менее важной проблемой.
Всего наилучшего.

@devel-pa, ошибки должны сказать вам, что компилятор понятия не имеет, что такое ваш импорт. любое последующее использование импорта не может быть проверено.

Отключение ошибок не решает никаких проблем. он просто молча проталкивает эти «неизвестные» по всей вашей системе. без информации о типе компилятор не может предупредить вас о том, что безопасно, а что нет. и в этом весь смысл TypeScript :)

Что касается сгенерированного JS. ни одна из ошибок типа TS не мешает генерировать ваш вывод. если вас не волнуют ошибки типов, просто игнорируйте их все. компилятор по-прежнему генерирует ваши соответствующие файлы .js.

Решение для отсутствующих определений состоит в том, чтобы объявить их. вам не нужно объявлять полную форму модуля, а только имя. Это позволяет компилятору узнать, что существует модуль «myLibrary», он может предупредить вас об опечатках в именах модулей и, что более важно, никакие другие модули не останутся непроверенными.

declare module "myLibrary" {
    var a: any;
    export = a;
}

как указано в # 6615, TypeScript скоро должен поддерживать более короткую форму.

Я думаю, что проблема в том, что это вызывает боль при адаптации проектов. Я думаю, что эта проблема аналогична неявному любому . Прямо сейчас этот импорт по существу подразумевается как void . Конечно, на ошибки можно не обращать внимания, но это вызывает много шума и идет вразрез с философией постепенного набора текста, а валидный JS — это валидный TS.

Я могу понять путаницу здесь для людей, плохо знакомых с TS. Если они активно использовали синтаксис модуля ES6 в JS, почему он просто не работает в TS? Что особенного в import from над var x = require , который _is_ рассматривается как неявный any. Первоначально import был ключевым словом, специфичным для TS, поэтому он подразумевал, что разработчик хотел, чтобы модуль рассматривался как типизированный модуль. Теперь, когда это не эксклюзивно для TS, я не думаю, что можно сделать такое предположение.

неявные ошибки возникают при объявлении переменных без указания типа. но использование необъявленной переменной по-прежнему является ошибкой. Для jquery вам все еще нужно где-то declare var $; , чтобы компилятор знал, что вы действительно хотели иметь глобальную переменную с именем $ , а не просто пропустить ее. это более или менее то же самое для модулей, компилятор должен знать, что есть модуль с именем "myLibrary" и это не имя, введенное с ошибкой. поэтому просто добавьте объявление для него.

во всяком случае, #6615 должен поддерживать добавление declare module "*"; для соответствия всем модулям в вашей системе, хотя я думаю, что если вы это сделаете, вы не получите никакой помощи от своего инструментария, и вы настраиваете себя на болезненную переход позже, когда вы решите удалить его.

@mhegazy Я понимаю ваши рассуждения, но у меня действительно проблема с этим обоснованием

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

Ситуация еще хуже с типизированными модулями (с записью typings в package.json), которые, как мы предполагаем, правильно типизированы, могут на самом деле использовать эти заполнители внутри.

Я понимаю, что эти заполнители нельзя предотвратить, но я бы предпочел, по крайней мере, чтобы они не поощрялись.
Что следует поддерживать, так это то, что по умолчанию импорт разрешается в any и что компилятор выдает предупреждение при каждой компиляции. Так что, по крайней мере, просматривая журналы компилятора/CI, мы знаем, что что-то потенциально подозрительно и нуждается в улучшении.

(с другой стороны, как указано на домашней странице typescriptlang.org, Typescript является «надмножеством» Javascript, и ИМХО любой допустимый синтаксис ES6 следует просто проглотить как есть)

Обходные пути и сокрытие мусора под ковром для меня самое худшее, что может случиться (помимо ES6 super).
Я постоянно работаю с библиотеками JS, и обычно с последними версиями как часть моей работы и дополнительного кода дома. 90% не типизированы или имеют старые определения, 9% не очень хорошо типизированы (поскольку компилятор не умеет делать одно определение для всех файлов). Ни у меня, ни у меня нет очень хороших определений по той же предыдущей причине и по той причине, что моей целью является JS, я не думаю, что мне нужно заботиться об исходном языке.
Кроме того, я видел причину, по которой существуют «неизвестные» библиотеки. Нет, совсем нет, если разработчики не знают и не понимают, какие библиотеки используются, зачем с ними возиться, я знаю, почему я их использую и зачем добавляю в стек. Предупреждения и тестов (если они есть) для этого достаточно.
Пожалуйста, сначала JavaScript, это цель и экосистема. TS — это просто аксессуар для лучшего кодирования и проверки типов во время компиляции, но только для того, что мы создаем. Остальное не касается машинописных текстов.
Хочу отметить, что я тоже был против nmps peerDependencies , выбирал я, а не софт. Императивное программирование, детка.

как насчет импорта модулей из каталога JSPM вместо node_modules?

редактировать: я нашел существующий билет -> https://github.com/Microsoft/TypeScript/issues/6012

Я только что столкнулся с проблемой разрешения модуля Node при использовании SystemJS для загрузки каталога:

По-видимому, в то время как Node (и, следовательно, TypeScript) понимает, что путь на самом деле является каталогом, и поэтому вместо этого загружает index.ts , SystemJS этого не делает, а это означает, что действительный код TS фактически не сможет загрузиться в браузере.

Это также верно для узловых модулей, которые имеют точку входа index.ts/js или даже используют свойство package.json main . С этим немного проще работать, потому что легко (хотя и повторяется) добавить конфигурацию пакета в SystemJS. Это не так просто при работе с произвольными каталогами.

Какое подходящее решение для этого?

Автоматическое разрешение модуля JSPM в настоящее время не поддерживается. это отслеживается https://github.com/Microsoft/TypeScript/issues/6012.

Рекомендуется использовать поддержку разрешения модулей сопоставления путей, см. https://github.com/Microsoft/TypeScript-Handbook/blob/release-2.0/pages/Module%20Resolution.md#path -mapping.

Приведенные выше инструкции являются началом, но некоторым людям может потребоваться сделать что-то еще... Возможно, вам придется добавить
<Folder Include="node_modules" />
в .njsproj

Больше информации

Я строил с помощью gulp, и у меня был TypeScriptCompileBlocked в .nsproj. Чтобы исправить проблемы с отладкой точек останова в VS 15 Preview 5 (я получал ошибку «кадр не в модуле») и проблемы, которые у меня были с intellisense, мне пришлось добавить в .njsproj . Этот каталог уже был там, когда я импортировал проект, но для него было задано значение git-ignore. Это моя теория о том, почему Visual Studio проигнорировала его (возможно, у него должно быть автоматическое исключение для node_modules?)

Помимо отладки и работы с IntelliSense, я также перестал видеть ошибки IntelliSense, помимо тех же самых ошибок, которые я видел в gulp во время его сборки, что и ожидалось.

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