使用 Typescript 扩展 Polka Request 对象

Extend Polka Request object using Typescript

首先,我知道这个主题看起来非常类似于 谈论 使用 Typescript 扩展 Express Request 对象

基本上,我尝试做同样的事情,但这次 Polka

有人成功做到了吗?

我走的路与

类似

在项目根目录下,我创建了这个文件夹结构:

app/
├─ src/
│  ├─ @types/
│  │  ├─ polka/
│  │  │  ├─ index.d.ts

然后我在 index.d.ts

中添加了这个
import * as polka from "polka";

declare global {
  namespace polka {
    interface Request {
      foo: string;
    }
  }
}

我还更新了我的 tsconfig.json 添加了这个 :

"typeRoots": [ "@types" ]

我为请求赋值的中间件如下所示

import type { Middleware } from "polka";

export const dummyMiddleware: Middleware = (req, res, next) => {

  req.foo = "hello";
  next();
};

通过这样做,我遇到了这个 Typescript 错误:

Property 'foo' does not exist on type 'Request<ParamsDictionary, any, any, ParsedQs,

当我看波尔卡 Middleware definition 我看到这种类型是通用的。

我试过这样做

import type { Middleware } from "polka";

export const dummyMiddleware: Middleware<{foo : string}> = (req, res, next) => {

  req.foo = "hello";
  next();
};

但是报错信息只变成这样

Property 'foo' does not exist on type 'Request<{ foo: string; }, any, any, ParsedQs, Record<string, any>>'.ts(2339)

所以,问题是,声明合并是实现这一目标的最佳方式吗?如果是的话,你有没有合适的方法来实现这个?

一些上下文,这个中间件将用于 seeding Sapper session data

版本:

完整的 TypeScript 配置:

{
        "extends": "@tsconfig/svelte/tsconfig.json",
        "compilerOptions": {
         "module": "esnext",
            "lib": ["DOM", "ES2017", "WebWorker", "ESNext"],
            "strict": true
        },
        "include": ["src/**/*", "src/node_modules/**/*"],
        "exclude": ["node_modules/*", "__sapper__/*", "static/*"],
        "typeRoots": [ "@types" ]
    }

免责声明:

我是波尔卡和打字稿的新手,所以我漏掉一些明显的东西并非不可能

我决定先将 IncomingMessage 转换为 Request

import { IncomingMessage, ServerResponse } from 'node:http';
import polka, { Next, Request } from 'polka';

function one(req:IncomingMessage, res:ServerResponse, next:Next) {
  (req as Request).foo = 'world';
  next();
}

function two(req:IncomingMessage, res:ServerResponse, next:Next) {
  //req.foo = '...needs better demo ';
  next();
}

const app = polka();
app.use(one, two);
app.get('/users/:id', (req:IncomingMessage, res) => {
  console.log(`~> Hello, ${(req as Request).foo}`);
  res.end(`User: ${(req as Request).params.id}`);
});
app.listen(3000, (err:any) => {
  if (err) throw err;
  console.log(`> Running on localhost:3000`);
});

然后在 index.d.ts 试试这个:

declare global{
  module 'polka' {
    interface Request {
      foo: string;
    }
  }
}

不太好,但可以使用。