8

I'm trying to create a extension on supertest.

Using what I found in question Extending SuperTest. I have this working example on 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);
}

And inside a test block I can use:

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

This works fine. The problem now is to use the extension in a *.test.ts file.

As suggested in Extend Express Request object using Typescript, I try to create a file to use the typescript feature Declaration Merging.

// 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.
  }
}

and also changed my tsconfig.json

{
  "compilerOptions": {

    ...

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

    ...

  }
}

But when I run npx tsc

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

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

Question
Is there a way to fix this on typescript environment?

[EDIT]
Extra Information (not necessarily useful):
In the same project I have extensions on express, chai and pdf-merge-js. All of them works fine using the approach described above.

There is something peculiar about supertest maybe about @types/supertest that is preventing it to work.

This is a little bit of the code in my project that already work's for express:

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

declare global {
  namespace Express {
    export interface Response {
      model: (model: ModelBase) => this;
    }
  }
}
7
  • At this answer Extend Express Request object using Typescript it says you have to add the whole file path to tsconfig.json files array, not typeRoots. Try to add the file to files inside tsconfig. Commented Apr 3, 2020 at 20:54
  • In my project I have extensions for express and chai all work perfectly, using this setup, only supertest didn't work. But I tested your theory anyway, didn't work, thanks for the help. Commented Apr 4, 2020 at 0:52
  • I updated the question with a little more information. Commented Apr 4, 2020 at 1:04
  • It's not my theory, it's what the answer you're referencing suggests and you're missing. Commented Apr 4, 2020 at 7:38
  • Can you try to add this file in your user.test.ts? Commented Apr 5, 2020 at 7:50

3 Answers 3

11

This one worked for me well.

First I've imported types

npm i -D @types/supertest  

And then I've used

import { agent as request } from "supertest"; 
Sign up to request clarification or add additional context in comments.

Comments

9
+50

I'm not sure why, but this worked for me:

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

Structure:

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

My 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();

My tsconfig.json:

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

My types/supertest/index.d.ts:

import superagent from "superagent";

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

I think that declare module "supertest" is the key part. Everything else you got right.

1 Comment

This worked even without changes on tsconfig.json. Thanks a lot.
-3

I'd trough with this problem and i solve it just import on test file

import { agent as request } from "supertest";

1 Comment

that makes no sense lmao

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.