簡體   English   中英

從typescript模塊自動生成index.d.ts,類型定義

[英]Auto generate index.d.ts, type definitions, from a typescript module

如果我將TypeScript模塊保存為my-function.ts,如下所示:

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

這將以任何方式編譯為JavaScript並且松散其類型定義。 然后我可以創建一個index.d.ts文件來聲明這個模塊的定義,但重新定義/重新定義這些定義似乎有點乏味。

有沒有辦法從my-function.ts文件自動生成類型定義到index.d.ts文件?

如果使用--declaration標志進行編譯,TypeScript將自動為您生成.d.ts文件。

此模式將要求您可以看到某些類型,以便可以在.d.ts文件中對其進行描述。

以下是我設法解決的方法:

創建基礎設施

  1. 使用infra的typescript創建一個新的Node包。
  2. 在新包中,確保使用聲明配置tsconfig.json :true這樣做會導致typescript生成可由此infra的用戶使用的定義文件。

我的tsconfig.json:

{
"compilerOptions": {
   "target": "es5",
   "module": "commonjs",
   "declaration": true,
   "outDir": "./tsOutputs"
 },
"include": [
  "lib/**/*.ts",
  "index.ts"
],
"exclude": [
  "test/**/*.ts"
]
  }
  1. 創建一個“index.ts”文件,該文件將導出infra的公共API。

注意:為了能夠轉換和創建對象的實例,每個實體需要有兩個不同的導出。 一次作為類型 ,另一個作為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”文件。 現在我們必須處理infra的package.json ,以便打包所有項目。

  2. package.json中,確保設置類型 main ,指向生成的index.d.tsindex.js文件。 此外,您必須確保將“* .d.ts”文件打包為infra的一部分。 在我的例子中,我在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. 安裝infra。 在我們的例子中,用戶必須使用: 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);
        }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM