合并 Socket.IO 的 TypeScript 接口声明不起作用

Merging TypeScript interface declaration for Socket.IO is not working

我一直在兜圈子寻找如何将 属性 添加到 Socket.IO v3 的界面。所以我很自然地查看了模块扩充和如何编写声明文件的 TypeScript 文档,但我无法让它工作,而且我不知道我做错了什么。所以发生的事情是 VSCode 抱怨 session 属性 在 Handshake 界面上不存在。

这就是我想要完成的:

// src/types/socket.io/index.d.ts
import { Session, SessionData } from "express-session";
import { EntityContext } from "../../contexts/EntityContext";

declare module "socket.io" {
  interface Handshake {
    session?: Session & Partial<SessionData>;
    sessionID?: string;
    context?: EntityContext;
  }
}

项目结构

- package.json
- tsconfig.json
- /src
    - /types
        - /socket.io
            - index.d.ts
- index.ts
// tsconfig.json
{
   "compilerOptions": {
      "lib": [
         "es5",
         "es6"
      ],
      "target": "es5",
      "module": "commonjs",
      "moduleResolution": "node",
      "outDir": "./build",
      "emitDecoratorMetadata": true,
      "experimentalDecorators": true,
      "sourceMap": true,
      "allowSyntheticDefaultImports": true,
      "baseUrl": ".",
      "typeRoots": [
         "node_modules/@types",
         "src/types"
      ],
      "paths": {
         "socket.io": ["node_modules/socket.io/dist", "src/types/socket.io"]
      }
   },
   "files": [
      "src/index.ts",
      "src/types/socket.io/index.d.ts"
   ]
}
// package.json
{
 ...
 "dependencies": {
    "apollo-server-express": "^2.21.1",
    "argon2": "^0.27.1",
    "connect-redis": "^5.1.0",
    "cors": "^2.8.5",
    "dataloader": "^2.0.0",
    "express": "^4.17.1",
    "express-session": "^1.17.1",
    "graphql": "^15.5.0",
    "pg": "^8.5.1",
    "redis": "^3.0.2",
    "reflect-metadata": "^0.1.10",
    "socket.io": "^3.1.2",
    "type-graphql": "^1.1.1",
    "typeorm": "0.2.31",
    "express-socket.io-session": "^1.3.5"
  },
  "devDependencies": {
    "@types/component-emitter": "^1.2.10",
    "@types/connect-redis": "0.0.16",
    "@types/cookie": "^0.4.0",
    "@types/cors": "^2.8.10",
    "@types/express": "^4.17.11",
    "@types/express-session": "^1.17.3",
    "@types/node": "^8.0.29",
    "@types/redis": "^2.8.28",
    "ts-node": "3.3.0",
    "typescript": "3.3.3333"
  }
}

我不知道你是否知道,但我几乎抓住了所有我发现的东西来尝试解决这个问题,但无济于事。我只是不明白声明应该如何工作..

如果有人能发现我犯的任何错误,或者如果你能给我指出可以解决 TypeScript 3 和 VSCode 这个问题的指南,我将不胜感激。

如果您需要更多信息,请告诉我,我会提供。

您的模块声明称为 'socket.io',因为您在 tsconfig 中映射了类型,但这不是必需的。您还映射了类型文件本身 "socket.io": ["node_modules/socket.io/dist", "src/types/socket.io"],这可能会破坏扩充。另外 node_modules/socket.io/dist 是错误的路径。正确的是 node_modules/socket.io/dist/socket。我建议删除完整的 path 配置,因为它只会让事情变得更难。

如果没有路径配置,您必须准确地告诉打字稿您想要扩充哪个模块,如 documentation 的示例所示。当您导入未增强的 Handshake 接口时,它通常来自 'socket.io/dist/socket'。因此,您将用于正常导入的路径,如 import { Handshake } from 'socket.io/dist/socket';,也是已声明模块的名称。如果你想合并声明而不是替换它,你还必须为原始 Handshake 接口添加一个导入。 *.d.ts 文件应如下所示:

import { Session, SessionData } from "express-session";
import { EntityContext } from "../../contexts/EntityContext";
// You need to import the original interface to extend it, if you don't,
// you will instead replace the orginal Handshake interface with your own definition. 
import { Handshake } from 'socket.io/dist/socket';

declare module 'socket.io/dist/socket' {
    interface Handshake {
        session?: Session & Partial<SessionData>;
        sessionID?: string;
        context?: EntityContext;
    }
}