【问题标题】:Auto generate index.d.ts, type definitions, from a typescript module从 typescript 模块自动生成 index.d.ts,类型定义
【发布时间】:2017-11-05 23:15:56
【问题描述】:

如果我有一个 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


    【解决方案1】:

    如果你使用--declaration 标志编译,TypeScript 会自动为你生成.d.ts 文件。

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

    【讨论】:

    • 有没有简单的方法来组合它们?如果这很重要,我说的是 UMD 模块。
    • 您可能在谈论声明捆绑(即将您的声明折叠到一个顶级 index.d.ts 文件),但 TypeScript 目前不支持。
    • 人们是如何把这个输入明确的?
    【解决方案2】:

    这是我设法解决的方法:

    创建基础设施

    1. 使用 typescript 为 infra 创建一个新的 Node 包。
    2. 在新包中,确保配置 tsconfig.jsondeclaration:true 这样做会导致 typescript 生成可供用户使用的定义文件这个基础。

    我的 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”文件。现在我们必须处理 infra 的 package.json,以便打包所有项目。

    2. package.json 中确保将 typesmain 设置为指向生成的 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. 安装基础设施。在我们的例子中,用户必须使用:npm install my-js-infra --save
    2. 修改消费应用程序的 tsconfig.json 以使用 Node 模块分辨率加载模块。您可以通过在文件中设置 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);
            }
    }
    

    【讨论】:

    • 我的index.tsmodule.exports = {...}。模块中的每个其他.ts 文件都会正确创建对应的.d.ts 文件,期望index.d.ts,它只是说export {};。有什么建议吗?!
    • 什么是“基础设施”?
    猜你喜欢
    • 2020-05-26
    • 2020-02-11
    • 1970-01-01
    • 2017-03-06
    • 2022-01-13
    • 2017-02-17
    • 1970-01-01
    • 2019-02-18
    • 2017-07-02
    相关资源
    最近更新 更多