【问题标题】:Generating TypeScript declarations for re-exported JS functions in a Node.js module为 Node.js 模块中重新导出的 JS 函数生成 TypeScript 声明
【发布时间】:2020-04-21 04:31:20
【问题描述】:

我正在尝试为使用 JSDoc 注释的类型和函数发出声明。这些对 TypeScript 用户很有用,从 JSDoc 生成它们意味着我们的 SDK 开发人员的开销更少。

TypeScript 用户应该获得一个名为 Apify 的模块,并从中访问我们的 SDK 功能。

import {Apify} from "apify";

const envs = Apify.getEnv();
...

这不会发生,生成的index.d.ts 包含多个模块,每个 JS 源文件一个。


情况

我的 JavaScript 库是客户端代码可见的单个模块。源码由src/目录下的多个文件组成:

  • src/index.js
  • src/actor.js
  • src/request.js
  • ...

index.js 文件重新导出其他文件中定义的函数,因此它们可以被运行在 Node.js 中的客户端代码访问。

import { main, getEnv, call, callTask, ... } from './actor';
import Request from './request';
...

/**
 * The following section describes all functions and properties provided by the `apify` package...
 *
 * @module Apify
 */
module.exports = {
    main,
    getEnv,
    ...
    Request,
    ...
};

package.json中,文件build/index.js被定义为入口点(被babel从src/index.js转译后):

{
   "main": "build/index.js",
   ...
}

我的tsconfig.json 如下:

{
    "compilerOptions": {
        "target": "esnext",
        "module": "esnext",
        "moduleResolution": "node",
        "lib": [
            "es2017",
            "dom"
        ],
        "allowJs": true,
        "checkJs": false,
        "noEmit": false,
        "declaration": true,
        "emitDeclarationOnly": true,
        "strict": false,
        "noImplicitThis": true,
        "alwaysStrict": true,
        "esModuleInterop": true,
        "outFile": "types/index.d.ts"
    },
    "include": [
        "src/index.js"
    ]
}


结果

运行tsc 后,我得到了我的types/index.d.ts,其中包含我的每个JS 源文件的模块声明(客户端代码无法访问它们中的每一个)和一个空的index 模块:

declare module "actor" {
    export function getEnv(): Env;
    export function main(userFunc: Function): void;
    ...
}
declare module "request" { ... }
...

declare module "index" {
    export {};
}

【问题讨论】:

  • 我正在为这个问题添加一个赏金,因为我遇到了同样的问题,这个问题有很多观点,目前的答案并不令人满意。一个好的答案将(imo):1. 描述在使用这种“从索引中重新导出所有内容”样式的模块设计时如何生成正确的声明文件,或者 2. 描述基于 typescript 的 npm 模块的正确组织结构以及如何在该设计下生成声明文件。

标签: node.js typescript jsdoc auto-generate typescript-declarations


【解决方案1】:

这个问题是因为您使用的是module.exports instead 导出default

改变

/**
 * The following section describes all functions and properties provided by the `apify` package...
 *
 * @module Apify
 */
module.exports = {
    main,
    getEnv,
    ...
    Request,
    ...
};


/**
 * The following section describes all functions and properties provided by the `apify` package...
 *
 * @module Apify
 */
export default {
    main,
    getEnv,
    ...
    Request,
    ...
};

然后让我们看看这个文件

actors.js

module.exports = {
    main: () => { console.log("main") },
    getEnv: () => { console.log("getEnv") }
}

request.js

module.exports = {
    Request: () => { console.log("req") }
}

index.js

import { main, getEnv } from './actor';
import Request from './request';

/**
 * The following section describes all functions and properties provided by the `apify` package...
 *
 * @module Apify
 */
export default {
    main,
    getEnv,
    Request,
};

使用 module.export

类型文件
declare module "actor" {
    export function main(): void;
    export function getEnv(): void;
}
declare module "request" {
    export function Request(): void;
}
declare module "index" {
    export {};
}

export default

declare module "actor" {
    export function main(): void;
    export function getEnv(): void;
}
declare module "request" {
    export function Request(): void;
}
declare module "index" {
    namespace _default {
        export { main };
        export { getEnv };
        export { Request };
    }
    export default _default;
    import { main } from "actor";
    import { getEnv } from "actor";
    import Request from "request";
}

【讨论】:

  • 我不记得我们是如何解决的,但解决方案与您描述的相似。
【解决方案2】:

你可以在索引上添加这个:

export {main, getEnv} from './actor';

【讨论】:

    猜你喜欢
    • 2016-12-06
    • 1970-01-01
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    • 1970-01-01
    • 1970-01-01
    • 2021-07-04
    相关资源
    最近更新 更多