从typescript模块自动生成index.d.ts,类型定义

时间:2017-06-05 08:16:50

标签: javascript node.js typescript node-modules type-definition

如果我将TypeScript模块保存为my-function.ts,如下所示:

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

这将以任何方式编译为JavaScript并且松散其类型定义。然后我可以创建一个index.d.ts文件来声明这个模块的定义,但重新定义/重新定义这些定义似乎有点乏味。

有没有办法从my-function.ts文件自动生成类型定义到index.d.ts文件?

2 个答案:

答案 0 :(得分:4)

如果您使用--declaration标记进行编译,TypeScript会自动为您生成.d.ts个文件。

此模式要求您可以看到某些类型,以便在.d.ts文件中对其进行描述。

答案 1 :(得分:3)

以下是我设法解决的问题:

创建基础

  1. 使用infra的打字稿创建一个新的Node包。
  2. 在新软件包中,确保使用声明配置 tsconfig.json :true 这样做会导致typescript生成可供用户使用的定义文件这个下属。
  3. 我的tsconfig.json:

    {
    "compilerOptions": {
       "target": "es5",
       "module": "commonjs",
       "declaration": true,
       "outDir": "./tsOutputs"
     },
    "include": [
      "lib/**/*.ts",
      "index.ts"
    ],
    "exclude": [
      "test/**/*.ts"
    ]
      }
    
    1. 创建一个“index.ts”文件,该文件将导出infra的公共API。
    2. 注意:为了能够施放&创建对象的实例,每个实体需要有两个不同的导出。一次为类型,另一次为 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. 完成以下所有操作后,当我们运行build时,每个类型都应该有相应的“* .d.ts”文件。现在我们必须处理infra的 package.json ,以便打包所有项目。

      2. package.json 中,确保将 types main 设置为指向生成的索引。 d.ts & index.js 文件。 此外,您必须确保将“* .d.ts”文件打包为infra的一部分。就我而言,我在 files 属性中指定了以下模式:“tsOutputs / ** / * .d.ts”

      3. 这是我的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 来实现此目的。
        3. 这是我的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. 开始使用代码。例如:
          2. 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);
                    }
            }