Автоматическое создание index.d.ts, определений типов, из модуля машинописного текста

Если у меня есть модуль TypeScript, сохраненный как my-function.ts следующим образом:

export function myFunction (param: number): number { return param }

Он будет скомпилирован в JavaScript каким-либо образом и потеряет определения типов. Затем я могу создать файл index.d.ts, который объявляет определения этого модуля, но это кажется немного утомительным для переопределения / повторного объявления определений.

Есть ли способы автоматически сгенерировать определения типов из файла my-function.ts в файл index.d.ts?


person altus    schedule 05.06.2017    source источник


Ответы (2)


Если вы компилируете с флагом --declaration, TypeScript автоматически сгенерирует для вас .d.ts файлы.

Этот режим потребует, чтобы вы были видны определенные типы, чтобы их можно было описать в ваших .d.ts файлах.

person Daniel Rosenwasser    schedule 05.06.2017
comment
Есть ли простой способ их совместить? Если это важно, я говорю о модулях UMD. - person nadavy; 21.12.2017
comment
Возможно, вы говорите об объединении деклараций (т. Е. Сворачивании ваших деклараций до одного index.d.ts файла верхнего уровня), но TypeScript в настоящее время не поддерживает это. - person Daniel Rosenwasser; 22.12.2017

Вот как мне удалось это решить:

Создание инфра

  1. Создайте новый пакет Node с машинописным текстом для инфра.
  2. Внутри нового пакета не забудьте настроить tsconfig.json с декларацией: true. Это приведет к тому, что машинописный текст будет генерировать файлы определений, которые могут быть использованы пользователями этой инфраструктуры. .

Мой tsconfig.json:

{
"compilerOptions": {
   "target": "es5",
   "module": "commonjs",
   "declaration": true,
   "outDir": "./tsOutputs"
 },
"include": [
  "lib/**/*.ts",
  "index.ts"
],
"exclude": [
  "test/**/*.ts"
]
  }
  1. Создайте файл "index.ts", который будет экспортировать общедоступный API инфраструктуры.

Примечание. Чтобы иметь возможность преобразовывать и создавать экземпляры объектов, вам необходимо иметь два разных экспорта для каждой сущности. Один раз как type, а другой как const.

Вот мой index.ts:

import {HttpClient as HC} from "./lib/http/http-client";

import {HttpRequest as HReq, HttpResponse as HRes}  from "./lib/http/contracts";

export namespace MyJsInfra

{

export type HttpClient = HC;

   export namespace Entities{
       export type HttpRequest = HReq;
       export const HttpRequest = HReq;

       export type HttpResponse = HRes;
       export const HttpResponse = HRes;
   }
}`

Подробнее о причинах этого двойного объявления можно прочитать здесь: https://github.com/Microsoft/TypeScript/issues/10058#issuecomment-236458961

  1. После всего следующего, когда мы запустим сборку, у нас должны быть соответствующие файлы «* .d.ts» для каждого типа. Теперь нам нужно обработать package.json инфра, чтобы упаковать все элементы.

  2. Внутри package.json не забудьте установить types, main так, чтобы они указывали на сгенерированный index.d.ts & index.js файлы. Кроме того, вы должны убедиться, что файлы «* .d.ts» упаковываются как часть инфраструктуры. В моем случае я указал следующий шаблон в свойстве files: "tsOutputs / ** / *. D.ts"

Вот мой package.json:

    {
  "name": "my-js-infra",
  "version": "1.0.0",
  "description": "Infrastructure code.",
  "scripts": {
    "build":"./node_modules/.bin/tsc -p .",
    "prepublish":"npm run build",
  },

 "homepage": "https://github.com/Nadav/My.JS.Infra#readme",
  "devDependencies": {
   ...
    "typescript": "^2.4.2",
   ...
  },
  "dependencies": {
     ...
    "needle": "^1.4.2",
     ...
  },
  "files": [
    "tsOutputs/**/*.js",
    "tsOutputs/**/*.d.ts",
    "tsOutputs/index.d.ts"
  ],
  "types":"tsOutputs/index.d.ts",
  "main":"tsOutputs/index.js"
}

Готово. Теперь вы можете опубликовать свой общий код.


Потребление кода

  1. Установите инфра. В нашем случае пользователь должен использовать: npm install my-js-infra --save
  2. Измените tsconfig.json приложения-потребителя, чтобы модули загружались с использованием разрешения модуля Узел. Для этого нужно установить в файле moduleResolution: true.

Вот мой tsconfig.json:

{
    "compilerOptions": {
        "target": "es5",
        "lib": ["es5", "es6"],
        "module": "umd",
        "sourceMap": true,
        "watch": false,
        "outDir": "./tsOutputs",
        "moduleResolution":"node" /* This must be specified in order for typescript to find the my-js-infra. Another option is to use "paths" and "baseUrl". Something like:
                                        ...
                                        "baseUrl": ".", // This must be specified if "paths" is used.
                                        "paths":{
                                            "my-js-infra":["node_modules/my-js-infra/tsOutputs/index.d.ts"]
                                        }
                                        ...
                                    */
    }
}

Подробнее о разрешении модулей в Typescript можно прочитать здесь: https://www.typescriptlang.org/docs/handbook/module-resolution.html

  1. Начните использовать код. Например:

import {MyJsInfra } from "my-js-infra";

public doMagic(cmd, callback) {
        try {
            var request:MyJsInfra.Entities.HttpRequest = {
                verb: "GET",
                url: "http://www.google.com",
            };

            var client = new MyJsInfra.HttpClient();
            client.doRequest(request, (err, data)=>{
                if (err)
                    return callback(err, null)
                return callback(null, data);
            })
        } catch (err) {
            callback(err);
        }
}
person nadavy    schedule 16.01.2018
comment
У моего index.ts есть module.exports = {...}. Каждый другой .ts файл в модуле получает соответствующий .d.ts файл, созданный должным образом, кроме index.d.ts, который просто говорит export {};. Какие-либо предложения?! - person masT; 24.04.2020