Синтаксис модуля Typescript ES6 с модулем ambient d.ts

Итак, давайте представим, что у меня есть модуль из 50 файлов, каждый из которых содержит:

export class <SomeClassName> { /* content */ }

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

export * from "./src/some-class-1";
export * from "./src/some-class-2";
export * from "./src/some-class-3";
// etc

Затем я запускаю его через TSC, чтобы создать «общий» модуль, нацеленный на «es5», с выводом дескриптора.

Все идет нормально. У меня package.json с именем my-module нацелена на вывод index.js в качестве точки входа для моего модуля. Итак, я решил использовать этот модуль в другом проекте машинописного текста.

Итак, я устанавливаю для него npm install (давайте притворимся) npm install my-module, и все это втягивается, так что теперь у меня есть файлы d.ts, которые были сгенерированы, и у меня есть фактический модуль commonjs, поэтому я могу использовать его все. Вроде все нормально.

Затем возникает проблема. Затем я решаю использовать модуль:

import {SomeClass1} from 'my-module'

Он взрывается, как в мире TS, он не знает, к чему относится my-module, как если бы мы вернулись и смотрим на выведенный index.js, он не содержит внешнего модуля.

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

export module "my-module" { /* all other re-exports */ }

Но оказывается, что вы можете использовать только строковые имена модулей для внешних модулей, и вы можете помещать их только в файлы d.ts, однако мой файл d.ts создается из существующей кодовой базы.

Итак, вот моя дилемма: я могу вручную войти и добавить оболочку declare module "my-module к моему d.ts, но это не очень автоматизировано, или мне нравятся сообщения в блоге с синтаксисом ES6 и ссылки на файл относительно, что в конечном итоге приведет к большому количеству of import {blah} from "../node_modules/my-module/dist/index", что, надеюсь, мы все можем согласиться, немного глупо.

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

Так есть ли способ обернуть мой реэкспорт в текстовое имя модуля? Или, по крайней мере, указать, что index.d.ts должен содержаться в внешнем модуле? (как помните, он будет выводить файл d.ts для каждого файла в проекте, но мы заботимся только об импорте модуля через index.d.ts, поскольку он повторно экспортирует все).


person Grofit    schedule 13.08.2015    source источник
comment
Вы можете создать отдельный d.ts файл, который ссылается на сгенерированный, и объявить там свой внешний модуль. Надеюсь, в этом больше не будет необходимости, когда люди переедут в System.js   -  person billc.cn    schedule 13.08.2015
comment
Это звучит как взлом, так как мне нужно было бы вручную написать этот файл, а затем спрятать его где-нибудь и вставить после завершения сборки. Если нет другого решения, я думаю, я смогу разобраться в этом, но, надеюсь, есть более элегантное решение, так как здесь это не похоже на СУМАСШЕДШИЙ вариант использования. Также я в настоящее время занимаюсь сборкой для системного типа модуля, но, похоже, есть некоторые проблемы с этим, и я думаю, что пройдет некоторое время, прежде чем nodejs станет достаточно простым для использования с модулями es6 без большого количества вещей во время выполнения babel.   -  person Grofit    schedule 13.08.2015
comment
Я только что попробовал это сейчас, так как кажется, что это не удалось error TS2439: Import or export declaration in an ambient module declaration cannot reference module through relative module name.   -  person Grofit    schedule 14.08.2015


Ответы (3)


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

  • dts-generator
  • dts-bundle
  • autodts - упрощает использование сгенерированных файлов .d.ts в пакетах, опубликованных в NPM.

Лично я использую настроенную версию dts-generator, которая использует tsconfig.json и работает с ночными сборками TypeScript. Вы можете увидеть .d.ts, созданный для одного из моих пакетов здесь.

person Vadim Macagon    schedule 15.08.2015
comment
Пакет выглядит так, как будто это может быть решение здесь, мы скоро попробуем его и дадим вам ответ, если он работает должным образом. - person Grofit; 15.08.2015
comment
В настоящее время, похоже, есть ошибка с dts-bundle (возникшая в связи с проблемами), которая останавливает его компиляцию, когда у вас есть не относительные модули (например, модуль стиля npm включает). Другой dts-generator, похоже, не поддерживает синтаксис ES6, поэтому его нельзя использовать в контексте этой проблемы. - person Grofit; 18.08.2015
comment
Попробуйте ветку ts-next в моей вилке dts-generator (ссылка в исходном ответе), она использует синтаксис ES6 и ночные сборки TypeScript (если вы хотите использовать последнюю стабильную версию TypeScript, вместо этого просто измените package.json) . - person Vadim Macagon; 18.08.2015
comment
Нужно ли мне предоставлять отдельные файлы или я могу просто включить baseDir? как если бы я это сделал, кажется, что он не нашел ни одной из типизаций, поэтому могу ли я использовать baseDir в качестве папки всех моих файлов d.ts и как-то обеспечить типизацию? (Я заметил внешний вид ссылочного синтаксиса, но это не очень ES6) - person Grofit; 18.08.2015
comment
Я ссылаюсь на все файлы .ts и .d.ts в tsconfig.json, устанавливаю параметр baseDir для каталога, содержащего tsconfig.json, и устанавливаю параметр excludes для соответствия .d.ts файлам, которые я не хочу встраивать в сгенерированный d.ts (даже если они не встроены они по-прежнему являются частью контекста компиляции, поэтому разрешение типов работает так, как и следовало ожидать) ... example < / а>. Поскольку я не встраиваю файлы .d.ts в сгенерированный .d.ts, я должен явно включать все соответствующие типы ввода в любой проект, который использует сгенерированный .d.ts. - person Vadim Macagon; 19.08.2015
comment
Я не использую файл tsconfig, так как выводит данные во многие типы модулей. Думаю, я могу добавить один исключительно для создания d.ts. - person Grofit; 19.08.2015

Хорошо, я наконец-то заработал, по крайней мере, для CommonJS.

Теперь с изменениями машинописного текста 1.6 разрешение модуля TS будет проверять папку node_modules на наличие index.d.ts файла. Итак, я в основном добавил этот файл в конце процесса сборки, который указывает на мой dist/definitions/index.d.ts файл, который включает все экспорты.

Таким образом, вы можете выполнить импорт, как import * from "my-module", и пока в вашей папке node_modules есть папка my-module с index.d.ts, он будет обрабатывать все в этом индексе как модуль.

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

person Grofit    schedule 08.10.2015
comment
Хотя все еще есть некоторые проблемы при создании файлов d.ts в проектах, которые зависят от такой системы включения. - person Grofit; 09.10.2015
comment
В настоящее время я пытаюсь заставить что-то подобное работать в проекте AMD, но я борюсь. Я создаю библиотеку под названием A, и я фактически вручную скопировал файлы d.ts, сгенерированные проектом, в node_modules/A/ и переименовал файл d.ts основного модуля в index.d.ts, но я все еще получаю ошибки компилятора, говорящие: 'Не удается найти модуль A '. - person jaker; 11.11.2015

Когда вы компилируете index.ts, вам нужно указать TSC сгенерировать для вас файл определения.

index.ts:

export * from "./src/some-class-1";
export * from "./src/some-class-2";
export * from "./src/some-class-3";

команда:

tsc --declaration index.ts

Это должно сгенерировать d.ts файл для индекса с экспортом в нем вместе с d.ts для каждого из some-class-* с их экспортом.

Конечно, для того, чтобы это работало, пользователю нужно будет сослаться на все d.ts файлы, которые на данный момент являются PITA; см. это. Я считаю, что вы можете использовать параметр --out, чтобы объединить все файлы в один, который включает d.ts. Хотя я тоже не уверен, что вы этого хотите.

person Micah Zoltu    schedule 14.08.2015
comment
out будет работать только в том случае, если вы не используете выходные данные модуля, насколько мне известно, также в настоящее время я выполняю указанную выше команду (через gulp typescript) для всех файлов, основная проблема заключается в том, что ни один из выходных файлов не будет содержать объявление модуля. Итак, index.d.ts выводится правильно и содержит все экспорты, просто если бы я попытался импортировать их import * from "my-module", как он узнает, что my-module? поскольку ни один из файлов объявлений не будет его содержать. - person Grofit; 14.08.2015