首页 > 解决方案 > Typescript 的声明合并使用 ts-node 无法按预期工作

问题描述

对于使用该express-session包的项目,我试图session通过简单地添加用户密钥来改变对象。

req.session.user = 123;

来自这个问题的接受答案,我知道我可以使用声明合并来扩展SessionData接口,使用我自己的接口。

查看各种开源项目,例如HospitalRun 组件存储库,我注意到它们的文件中的types目录如下所示。tsconfig.jsoninclude

  "include": [
    "src",
    "types"
  ]

我的整体tsconfig.json看起来像这样,它存在于项目的根目录中。

{
    "include": [
        "types",
        "src",
    ],
    "exclude": [
        "node_modules"
    ],
    "compilerOptions": {
        "lib": [
            "esnext",
            "esnext.asynciterable"
        ],
        "baseUrl": ".",
        "skipLibCheck": true,
        "module": "commonjs",
        "esModuleInterop": true,
        "target": "es6",
        "moduleResolution": "node",
        "outDir": "build",
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "allowSyntheticDefaultImports": true,
        "strict": true,
        "strictPropertyInitialization": false,
    },
}

我尝试做同样的事情,express-session.d.ts在这个文件夹的根目录中调用一个文件 ( ~/types/),具有以下内容:

import session from 'express-session';

declare module 'express-session' {
    interface SessionData {
        user: any;
    }
} 

但是,我一直收到的错误是这个。

 Property 'user' does not exist on type 'Session & Partial<SessionData>'

但是,当我在用于改变会话对象的代码上方添加这段代码时,我不再遇到问题。不过,这似乎不是正确的方法。

此外,当我使用它tsc src/index.ts --build而不是ts-node src/index.ts它时也可以。

我在这里做错了什么?如何解决这个问题?我也尝试使用typeRoots, 使用相同的文件夹。

标签: javascriptnode.jstypescriptexpresssession

解决方案


最新更新(2021 年 5 月 8 日)

使用 运行 typescript 程序时ts-node,即使typeRoots在 tsconfig.json 中指定,也无法识别自定义 .d.ts 并提示Property 'x不存在 type y` 错误。

根据https://github.com/TypeStrong/ts-node/issues/1132#issuecomment-716642560

ts-node提出多种解决方法的贡献者之一。

这是其中之一:指定file: true标志tsconfig.json以通知ts-node加载filesinclude以及启动时的exclude选项tsconfig.json

{
  "ts-node": {
    "files": true
  },
  "exclude": [...],
  "compilerOptions": {
   ...
}

旧:(2021 年 5 月 7 日)

不需要使用includein tsconfig.json,路径不正确。编译器可以搜索目录和子目录下的ts文件

尝试删除它。并重新启动 TS 服务器。

如果你用的是VSCode,试试++或者++ Cmd,搜索Shift一下,看看用户类型错误是否依然存在PCtrlShiftPRestart TS server

{
    "exclude": [
        "node_modules"
    ],
    "compilerOptions": {
        "lib": [
            "esnext",
            "esnext.asynciterable"
        ],
        "baseUrl": ".",
        "skipLibCheck": true,
        "module": "commonjs",
        "esModuleInterop": true,
        "target": "es6",
        "moduleResolution": "node",
        "outDir": "build",
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "allowSyntheticDefaultImports": true,
        "strict": true,
        "strictPropertyInitialization": false,
    },
}

推荐阅读