ค้นหาเว็บไซต์

node.js - การขยาย supertest ใน Typescript


ฉันกำลังพยายามสร้างส่วนขยายบน supertest

โดยใช้สิ่งที่ฉันพบในคำถาม Extending SuperTest ฉันมีตัวอย่างที่ใช้งานได้บน javascript:

const request = require('supertest');
const Test = request.Test;

Test.prototype.authenticate = function(user) {
  const {token, xsrfToken} = user.tokens;

  return this
   .set('Authorization', `Bearer ${token}`)
   .set('X-XSRF-TOKEN', xsrfToken);
}

และภายในบล็อกทดสอบฉันสามารถใช้:

request(app)
  .post('/user/settings')
  .authenticate(user)
  .send(...)

สิ่งนี้ใช้งานได้ดี ปัญหาตอนนี้คือการใช้ส่วนขยายในไฟล์ *.test.ts

ตามที่แนะนำใน Extend Express Request object โดยใช้ Typescript ฉันพยายามสร้างไฟล์เพื่อใช้ฟีเจอร์ Declaration Merging ของ Typescript

// file location: ./src/types/supertest

declare namespace supertest {
  export interface Test {
    authenticate(user: any): this; // I didn't put a type on user to simplify here.
  }
}

และยังได้เปลี่ยน tsconfig.json ของฉันด้วย

{
  "compilerOptions": {

    ...

    "typeRoots": ["./src/types"],

    ...

  }
}

แต่เมื่อฉันรัน npx tsc

npx tsc
src/api/user.test.ts:51:8 - error TS2551: Property 'authenticate' does not exist on type 'Test'.

51       .authenticate(user);
          ~~~~~~~

คำถาม
มีวิธีแก้ไขสิ่งนี้ในสภาพแวดล้อมของ TypeScript หรือไม่?

[แก้ไข]
ข้อมูลเพิ่มเติม (อาจไม่จำเป็นต้องมีประโยชน์):
ในโปรเจกต์เดียวกันนี้ ฉันมีส่วนขยายบน express, chai และ pdf-merge-js ทั้งหมดทำงานได้ดีโดยใช้วิธีการที่อธิบายไว้ข้างต้น

มีบางสิ่งที่แปลกเกี่ยวกับ supertest บางทีเกี่ยวกับ @types/supertest ที่ทำให้มันไม่ทำงาน

นี่คือตัวอย่างโค้ดบางส่วนในโปรเจกต์ของฉันที่สามารถใช้งานได้กับ Express แล้ว:

// file location: ./src/types/express
import { ModelBase } from '../../models/base';

declare global {
  namespace Express {
    export interface Response {
      model: (model: ModelBase) => this;
    }
  }
}

คำตอบ #1

อันนี้ใช้ได้ผลดีกับฉัน

ก่อนอื่นฉันได้ทำการนำเข้าประเภท

npm i -D @types/supertest  

แล้วฉันก็ได้ใช้

import { agent as request } from "supertest"; 

คำตอบ #2

ฉันไม่แน่ใจว่าเพราะอะไร แต่สิ่งนี้ใช้ได้ผลกับฉัน:

declare module "supertest" {
  interface Test extends superagent.SuperAgentRequest {
    authenticate(user: any): this;
  }
}

โครงสร้าง:

index.ts
tsconfig.json
types
  - supertest
    - index.d.ts

ไฟล์ index.ts ของฉัน:

import request from "supertest";
import express from "express";

const app = express();

app.get("/user", function (req, res) {
  res.status(200).json({ name: "john" });
});

request(app)
  .post("/user/settings")
  .authenticate({ tokens: { token: "", xsrfToken: "" } })
  .send();

ไฟล์ tsconfig.json ของฉัน:

{
  "compilerOptions": {
    "outDir": "dist",
    "rootDir": ".",
    "typeRoots": ["./types", "./node_modules/@types"],
    "esModuleInterop": true
  },
  "files": ["./types/supertest/index.d.ts", "index.ts"]
}

ไฟล์ types/supertest/index.d.ts ของฉัน:

import superagent from "superagent";

declare module "supertest" {
  interface Test extends superagent.SuperAgentRequest {
    authenticate(user: any): this;
  }
}

ฉันคิดว่า declare module "supertest" เป็นส่วนสำคัญ ทุกอย่างอื่นที่คุณทำถูกต้องแล้ว

บทความที่เกี่ยวข้อง