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;
}
}
}
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.
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";
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With