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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44364578/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 04:36:23  来源:igfitidea点击:

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

javascriptnode.jstypescriptnode-modulestype-definition

提问by altus

If I have a TypeScript module saved as my-function.ts as follows :

如果我有一个 TypeScript 模块保存为 my-function.ts 如下:

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

This will be compiled to JavaScript in whichever way and loose its type definitions. I am then able to create a index.d.ts file which declare this module's definitions, but this seems a bit tedious to redefine/redeclare the definitions.

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

Are there ways to generate the type definitions automatically from the my-function.ts file to a index.d.ts file?

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

回答by Daniel Rosenwasser

If you compile with the --declarationflag, TypeScript will automatically generate .d.tsfiles for you.

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

This mode will require that you certain types are visible so that they can be described in your .d.tsfiles.

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

回答by nadavy

Here's how I managed to solve it:

这是我设法解决它的方法:

Creating the infra

创建基础设施

  1. Create an new Node package with typescript for the infra.
  2. Inside the new package, make sure to configure a tsconfig.jsonwith declaration:trueDoing so will cause typescript to generate definition files which can be consumed by the users of this infra.
  1. 为基础创建一个带有打字稿的新节点包。
  2. 在新包中,确保使用声明配置tsconfig.json :true这样做会导致打字稿生成定义文件,这些文件可以被此基础设施的用户使用。

My tsconfig.json:

我的 tsconfig.json:

{
"compilerOptions": {
   "target": "es5",
   "module": "commonjs",
   "declaration": true,
   "outDir": "./tsOutputs"
 },
"include": [
  "lib/**/*.ts",
  "index.ts"
],
"exclude": [
  "test/**/*.ts"
]
  }
  1. Create a an "index.ts"file which will export the public API of the infra.
  1. 创建一个“index.ts”文件,该文件将导出基础设施的公共 API。

Note:In order to be able to cast & create instances of objects, you need to have two differentexports per each entity. Once as typeand another as const.

注意:为了能够投射和创建对象实例,每个实体需要有两个不同的导出。一次作为type,另一个作为const

Here's my index.ts:

这是我的 index.ts:

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

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 type HttpClient = HC;

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

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

You can read more info on the reasoning behind this dual declaration in here: https://github.com/Microsoft/TypeScript/issues/10058#issuecomment-236458961

您可以在此处阅读有关此双重声明背后的推理的更多信息:https: //github.com/Microsoft/TypeScript/issues/10058#issuecomment-236458961

  1. After all of the following, when we'll run build we should have the corresponding "*.d.ts" files per each type. Now we have to handle the package.jsonof the infra, in order to pack all the items.

  2. Inside the package.jsonmake sure to set the types, mainto point to the generated index.d.ts& index.jsfiles. In addition, you have to make sure that the "*.d.ts" files are being packaged as part of infra. In my case, I've specified the following pattern in the filesproperty: "tsOutputs/**/*.d.ts"

  1. 完成以下所有操作后,当我们运行 build 时,每种类型都应该有相应的“*.d.ts”文件。现在我们必须处理infra的package.json,以便打包所有项目。

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

Here's my package.json:

这是我的 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"
}

All done. Now you can publish your common code.

全做完了。现在您可以发布您的公共代码。



Consuming the code

消费代码

  1. Install the infra. In our case the user have to use: npm install my-js-infra --save
  2. Modify the tsconfig.jsonof the consuming application to load the modules using the Nodemodule resolution. You do so by setting moduleResolution:trueinside the file.
  1. 安装基础设施。在我们的例子中,用户必须使用:npm install my-js-infra --save
  2. 修改消费应用程序的tsconfig.json以使用Node模块解析加载模块。您可以通过在文件中设置moduleResolution:true来实现。

Here's my tsconfig.json:

这是我的 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"]
                                        }
                                        ...
                                    */
    }
}

You can read more on module resolution in Typescriptin here: https://www.typescriptlang.org/docs/handbook/module-resolution.html

您可以在此处阅读有关Typescript模块分辨率的更多信息:https: //www.typescriptlang.org/docs/handbook/module-resolution.html

  1. Start using the code. For example:
  1. 开始使用代码。例如:

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

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);
        }
}