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

问题描述 投票:2回答:2

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

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

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

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

javascript node.js typescript node-modules type-definition
2个回答
4
投票

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

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


2
投票

以下是我设法解决的方法:

创建基础设施

  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.ts和index.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"]
                                        }
                                        ...
                                    */
    }
}

您可以在这里阅读有关模块分辨率的更多信息: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);
        }
}
© www.soinside.com 2019 - 2024. All rights reserved.