Как вы создаете файл определения .d.ts «typings» из существующей библиотеки JavaScript?

193

Я использую много библиотек, как своих, так и сторонних. Я вижу, что каталог "typings" содержит некоторые для Jquery и WinRT ... но как они создаются?

Hotrodmonkey
источник

Ответы:

232

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

Может быть, он уже существует

Всегда сначала проверяйте DefinitiveTyped ( https://github.com/DefiniteTyped/DefiniteTyped ). Это репозиторий сообщества, полный буквально тысяч файлов .d.ts, и вполне вероятно, что то, что вы используете, уже есть. Вам также следует проверить TypeSearch ( https://microsoft.github.io/TypeSearch/ ), который является поисковым механизмом для опубликованных NPM файлов .d.ts; это будет иметь немного больше определений, чем DefinitiveTyped. Несколько модулей также поставляют свои собственные определения как часть своего дистрибутива NPM, поэтому также посмотрите, так ли это, прежде чем пытаться написать свои собственные.

Может быть, вам не нужен

TypeScript теперь поддерживает --allowJsфлаг и сделает больше выводов на основе JS в файлах .js. Вы можете попробовать включить файл .js в компиляцию вместе с --allowJsнастройкой, чтобы проверить, дает ли это достаточно хорошую информацию о типе. TypeScript распознает такие вещи, как классы в стиле ES5 и комментарии JSDoc в этих файлах, но может сработать, если библиотека странным образом инициализирует себя.

Начните с --allowJs

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

Начните с dts-gen

Если --allowJsэто не сработало, вы можете использовать dts-gen ( https://github.com/Microsoft/dts-gen ), чтобы получить отправную точку. Этот инструмент использует форму объекта во время выполнения для точного перечисления всех доступных свойств. С положительной стороны это имеет тенденцию быть очень точным, но инструмент еще не поддерживает очистку комментариев JSDoc для заполнения дополнительных типов. Вы запускаете это так:

npm install -g dts-gen
dts-gen -m <your-module>

Это сгенерирует your-module.d.tsв текущей папке.

Нажмите кнопку повтора

Если вы просто хотите сделать все это позже и какое-то время обходиться без типов, в TypeScript 2.0 вы можете написать

declare module "foo";

который позволит вам importв "foo"модуль с типом any. Если у вас есть глобальный, с которым вы хотите иметь дело позже, просто напишите

declare const foo: any;

который даст вам fooпеременную.

Райан Кавано
источник
25
Ох ... это будет серьезным препятствием для входа во многих случаях. Было бы неплохо иметь инструмент, который мог бы выводить хотя бы «лучшие догадки» на основе вывода типа. Хотя они могут быть неоптимальными, они могут по крайней мере настраиваться с течением времени.
Hotrodmonkey
7
+1 - еще одна хорошая новость: --declarationsгенерирует как .jsфайл, так и .d.tsфайл, что означает, что вам нужно всего лишь запустить одну компиляцию.
Фентон
67
Собрание высококачественных определений для популярных библиотек можно найти по адресу github.com/borisyankov/DefiniteTyped
Борис Янков,
10
Инструмент «наилучшего предположения» не будет лучше, чем IntelliSense, уже существующий в TypeScript. Преимущество определений типов заключается в том, что они предоставляют компилятору больше информации, чем он может «догадаться».
Борис Янков
12
--allowJsс --declarationпараметрами не могут быть объединены (проверено в TypeScript 1.8 и 2.0). Если я попытаюсь, я получу:error TS5053: Option 'allowJs' cannot be specified with option 'declaration'
Алексей
53

Вы можете использовать tsc --declaration fileName.tsкак Райан описывает, или вы можете указать declaration: trueпри compilerOptionsв вашем tsconfig.jsonпредположении , что вы уже имели tsconfig.jsonпод свой проект.

JayKan
источник
4
Это лучший ответ, если вы разрабатываете модуль Angular 2, которым хотите поделиться.
Дарси
Если я попытаюсь tsc --declaration test.tsполучить ошибку Cannot find name...для типов, для которых я пытаюсь создать файл объявления :) Итак, мне нужны типы, прежде чем я смогу их объявить?
Кокодоко,
2
@Kokodoko, вы можете попробовать добавить declaration: trueв свой tsconfig.jsonфайл?
JayKan
Спасибо, я просто хотел сгенерировать * .d.ts из * .ts.
Винтпроект
16

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

Горги Косев
источник
15

Как говорит Райан, компилятор tsc имеет переключатель, --declarationкоторый генерирует .d.tsфайл из .tsфайла. Также обратите внимание, что (исключая ошибки) предполагается, что TypeScript способен компилировать Javascript, поэтому вы можете передавать существующий код javascript в компилятор tsc.

CCoder
источник
1
Кажется, что в настоящее время передача файлов * .js в tsc приводит к ошибке "Ошибка чтения файла" angular-resource.js ": Файл не найден". Поэтому вы должны явно переименовать файлы * .js в * .ts, чтобы иметь возможность использовать tsc. См. Эту проблему для получения более подробной информации - я пытался использовать это на angularjs: typescript.codeplex.com/workitem/26
Джеймс
3
из того, что я могу сказать, tsc может скомпилировать любой допустимый JavaScript, но если он не является допустимым TypeScript (компиляция выдает предупреждения), то флаг --declarations не выводит файл .d.ts, поэтому, если ваша библиотека не написана на TypeScript, вы можете еще нужно вручную создать файл объявлений.
августа
3

Вот некоторый PowerShell, который создает один файл определения TypeScript, библиотеку, которая включает несколько *.jsфайлов с современным JavaScript.

Сначала измените все расширения на .ts.

Get-ChildItem | foreach { Rename-Item $_ $_.Name.Replace(".js", ".ts") }

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

Get-ChildItem | foreach { tsc $_.Name  }

Наконец, объедините все *.d.tsфайлы в один index.d.ts, удалив importоператоры и удалив defaultиз каждого оператора экспорта.

Remove-Item index.d.ts; 

Get-ChildItem -Path *.d.ts -Exclude "Index.d.ts" | `
  foreach { Get-Content $_ } | `
  where { !$_.ToString().StartsWith("import") } | `
  foreach { $_.Replace("export default", "export") } | `
  foreach { Add-Content index.d.ts $_ }

Это заканчивается одним пригодным для использования index.d.tsфайлом, который включает в себя множество определений.

Шон Луттин
источник
2
Второй шаг, Get-ChildItem | foreach {tsc --declaration $ _. Name} сработал (добавлен пропущенный параметр --declaration)
Guru_07
2

Я бы искал существующее отображение ваших сторонних JS-библиотек, которые поддерживают Script # или SharpKit. Пользователи этих кросс-компиляторов C # to .js столкнутся с проблемой, с которой вы сейчас столкнулись, и, возможно, опубликовали программу с открытым исходным кодом для сканирования вашей сторонней библиотеки lib и преобразования в скелетные классы C #. Если это так, взломайте программу сканера, чтобы сгенерировать TypeScript вместо C #.

В противном случае преобразование общедоступного интерфейса C # для вашей сторонней библиотеки в определения TypeScript может быть проще, чем делать то же самое, читая исходный JavaScript.

Меня особенно интересует среда ExtJS RIA от Sencha, и я знаю, что были опубликованы проекты по созданию интерпретации C # для Script # или SharpKit

верблюжьего
источник
К вашему сведению: я только что сделал свой первый файл определения машинописи для Sencha / ExtJS: github.com/andremussche/extjsTypescript/blob/master/jsondocs/…
Андре
Привет, Кэмел Кейс, я собрал блог об использовании ExtJs с машинописью: blorkfish.wordpress.com/2013/01/28/using-extjs-with-typescript
blorkfish
2

При создании вашей собственной библиотеки вы можете создавать *.d.tsфайлы с помощью команды tsc(TypeScript Compiler), например, так: (при условии, что вы собираете свою библиотеку в dist/libпапку)

tsc -d --declarationDir dist/lib --declarationMap --emitDeclarationOnly
  • -d( --declaration): генерирует *.d.tsфайлы
  • --declarationDir dist/lib: Выходной каталог для сгенерированных файлов объявлений.
  • --declarationMap: Создает исходную карту для каждого соответствующего файла .d.ts.
  • --emitDeclarationOnly: Только генерировать файлы объявлений '.d.ts'. (без скомпилированного JS)

(см. документацию по всем параметрам компилятора командной строки)

Или, например, в вашем package.json:

"scripts": {
    "build:types": "tsc -d --declarationDir dist/lib --declarationMap --emitDeclarationOnly",
}

а затем запустить: yarn build:types(или npm run build:types)

magikMaker
источник
Я до сих пор не могу понять, как создавать d.tsфайлы и использовать интерфейсы. У вас есть примеры?
Danosaure
Приведенный выше скрипт npm сгенерирует *.d.tsфайлы и поместит их в dist/libпапку. Вам нужен tsconfig.jsonфайл в корне вашего проекта, но он должен быть там, чтобы проект работал в любом случае.
magikMaker
Я не могу их использовать, когда-то разоблачен. У меня есть следующий пост stackoverflow.com/questions/59742688, если вы можете заставить его работать?
Данозавр