【问题标题】:Debugging TypeScript Node.js Compilation Error调试 TypeScript Node.js 编译错误
【发布时间】:2020-08-14 10:02:28
【问题描述】:

我正在尝试在 2019 项目上设置调试环境,因此我将以下脚本添加到我的 package.json

"dev:debug": "tsc-watch --onFirstSuccess \"node --inspect -r ts-node/register src/app.ts\"",

运行它会给我以下信息

> node-api-starter@1.0.0 start:dev D:\p\my-project
> tsc-watch --onFirstSuccess "node --inspect -r ts-node/register src/app.ts"

7:18:10 AM - Starting compilation in watch mode... 


7:18:27 AM - Found 0 errors. Watching for file changes.
Debugger listening on ws://127.0.0.1:9229/b9a130c4-473d-4b55-a512-50ae9cff15a3
For help, see: https://nodejs.org/en/docs/inspector
D:\p\my-project\node_modules\ts-node\src\index.ts:423
    return new TSError(diagnosticText, diagnosticCodes)
           ^
TSError: ⨯ Unable to compile TypeScript:
src/api/auth/auth.controller.ts:580:29 - error TS2339: Property 'auth' does not exist on type 'Request<ParamsDictionary>'.

580     user.refreshToken = req.auth.refreshToken; 
                                ~~~~
src/api/auth/auth.controller.ts:581:23 - error TS2339: Property 'user' does not exist on type 'Request<ParamsDictionary>'.

581     user.userId = req.user.id;
                          ~~~~
src/api/auth/auth.controller.ts:617:82 - error TS2339: Property 'auth' does not exist on type 'Request<ParamsDictionary>'.

617     const user = await userService.getUserInfoByCustomColumn("refreshToken", req.auth.refreshToken);

                                  ~~~~
src/api/auth/auth.controller.ts:782:76 - error TS2339: Property 'user' does not exist on type 'Request<ParamsDictionary>'.

782     const user = await userService.getUserInfoByCustomColumn("userId", req.user.id, true);        

                            ~~~~
src/api/auth/auth.controller.ts:800:46 - error TS2339: Property 'user' does not exist on type 'Request<ParamsDictionary>'.

800     await userService.updateUserPassword(req.user.id, insertedNewPassword);
                                                 ~~~~

    at createTSError (D:\p\my-project\node_modules\ts-node\src\index.ts:423:12)
    at reportTSError (D:\p\my-project\node_modules\ts-node\src\index.ts:427:19)
    at getOutput (D:\p\my-project\node_modules\ts-node\src\index.ts:554:36)
    at Object.compile (D:\p\my-project\node_modules\ts-node\src\index.ts:760:32)
    at Module.m._compile (D:\p\my-project\node_modules\ts-node\src\index.ts:839:43)
    at Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Object.require.extensions.(anonymous function) [as .ts] (D:\p\my-project\node_modules\ts-node\src\index.ts:842:12)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)

一个错误的例子

auth.controller.ts - Line 577

const refresh = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const user = new User();
    user.refreshToken = req.auth.refreshToken;
    ...
}

Request 是 Express 库的一部分

    interface Request<P extends core.Params = core.ParamsDictionary> extends core.Request<P> { }

有 2 个文件声明 Express 命名空间并导出 Request 具有不同变量的接口(见下文)

request.d.ts

declare namespace Express {
  export interface Request {
    user?: any;
    auth?: any;
  }
}

declarations.d.ts

declare module 'draftjs-to-html';

declare namespace Express {
  export interface Request {
    availableCountries: number[];
    language: string;
    pagination: {
      pageSize: number;
      pageNumber: number;
    };
  }
}

所以这里发生的情况是,使用tsc-watch 的第一次编译成功完成,但随后项目中弹出一些错误。

  • 这是否意味着ts-node 试图重新编译?
  • 如果是这样,为什么会失败?它是否使用与tsc-watch 不同的配置进行编译?
  • 有没有可以用来跳过检查这些错误的标志

【问题讨论】:

  • 能否给出相关代码以及Request&lt;T&gt;ParamsDictionary的类型
  • @MikeS。刚刚更新了描述,Request基本就是标准快递Request
  • 嗯,对吗?或者Request&lt;ParamsDictionary&gt;类型上是否有属性auth
  • 实际上有一个request.d.ts文件,其内容声明了命名空间Express,并在其Request接口中添加了userauth。还有另一个名为declarations.d.ts 的文件,它的作用完全相同,但变量不同。 (将其内容添加到说明中)。

标签: node.js typescript express debugging ts-node


【解决方案1】:

首先,ts-node 会重新构建您的源代码,因此您需要执行两次编译工作。不知道是不是这个问题,可能ts-node找不到你的tsconfig

作为一个直接的解决方法,我建议 merging 现有的 express.Request 声明,无论你的情况是什么,都用你自己的。基本上,您将来自 request.d.ts 的声明放在源代码中的某个位置,它可用于您的控制器功能,并在需要时使用适当的类型进行更新(或使用 any 滚动):

declare global {
    export namespace Express {
        export interface Request {
            user?: any;
            auth?: {refreshToken: string};
        }
    }
}

现在Request 显示正确键入的refreshToken

【讨论】:

  • 感谢您提供 TypeScript 修复建议。我们最终使用了没有 ts-node 的 nodemon。我仍然不明白为什么 ts-node 找不到相同的 tsconfig。但这是夏天的主题:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-01
  • 2011-05-14
  • 2019-09-22
  • 2017-04-02
  • 2012-11-15
  • 1970-01-01
  • 2017-08-06
相关资源
最近更新 更多