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

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

Ответ 1

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

Возможно, он уже существует

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

Возможно, вам не нужен

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

Начните с --allowJs

Если --allowJs дал вам достойные результаты, и вы хотите сами написать файл с более высоким разрешением, вы можете объединить --allowJs с --declaration, чтобы увидеть TypeScript "наилучшее предположение" в типах библиотеки. Это даст вам достойную отправную точку и может быть таким же хорошим, как файл, созданный вручную, если комментарии 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.

Ответ 2

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

Ответ 3

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

Ответ 4

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

Ответ 6

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

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

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

Ответ 7

Вот несколько 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 файлом, который включает в себя многие определения.

Ответ 8

При создании своей собственной библиотеки вы можете создавать файлы *.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: только создавать файлы объявлений declaration.d.ts. (без скомпилированного JS)

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

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

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

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