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

Posted

技术标签:

【中文标题】从 typescript 模块自动生成 index.d.ts,类型定义【英文标题】:Auto generate index.d.ts, type definitions, from a typescript module 【发布时间】: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 文件?

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

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

这是我设法解决的方法:

创建基础设施

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

我的 tsconfig.json:


"compilerOptions": 
   "target": "es5",
   "module": "commonjs",
   "declaration": true,
   "outDir": "./tsOutputs"
 ,
"include": [
  "lib/**/*.ts",
  "index.ts"
],
"exclude": [
  "test/**/*.ts"
]
  
    创建一个 "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

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

    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"

全部完成。现在你可以发布你的通用代码了。


消费代码

    安装基础设施。在我们的例子中,用户必须使用:npm install my-js-infra --save 修改消费应用程序的 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

    开始使用代码。例如:

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 ;。有什么建议吗?! 什么是“基础设施”?

以上是关于从 typescript 模块自动生成 index.d.ts,类型定义的主要内容,如果未能解决你的问题,请参考以下文章

如何从 typescript 使用 npm 模块?

Typescript、index.d.ts 和 webpack:找不到模块错误

TypeScript 打字给我“index.d.ts 不是模块”

Bootstrap4 打字(index.d.ts)无法在 VisualStudio 2019 上使用 TypeScript3.9 和 Libman 找到模块“popper.js”

如何在 TypeScript npm 模块中导出类型

如何从 TypeScript 文件生成类型定义文件?