supertest icon indicating copy to clipboard operation
supertest copied to clipboard

Support Typescript generic to type the response body

Open jasonlimantoro opened this issue 4 years ago • 7 comments

Consider this example,

const agent = supertest.agent(expressApp);
const response = await agent.post("/graphql").send({
    key: "value"
});

The type of response.body is any.

Ideally, we should be able to provide the TS generic for the body response, considering that the body is the most important part of the response to be tested.

The intended API may look similar to the following:

const response = await agent.post<{ data: { token: string} }>("/graphql").send({
    key: "value" 
});

// now response.body is typed as { data: { token: string } }

jasonlimantoro avatar May 27 '21 07:05 jasonlimantoro

Also, it would be great if send's type can be set

TriStarGod avatar Jun 10 '21 22:06 TriStarGod

I hope my comment helps up the priority, because I need this feature as well

maximkoev avatar May 17 '22 19:05 maximkoev

This would be really convenient!

varszegik avatar Jun 17 '22 09:06 varszegik

Also, it would be great if send's type can be set

https://github.com/microsoft/DefinitelyTyped-tools/blob/master/packages/dtslint/docs/no-unnecessary-generics.md this prevents me from making a PR to add generic type vaiant of Request#send() to superagent.

See https://github.com/DevDengChao/DefinitelyTyped/blob/superagent/types/superagent/superagent-tests.ts#L11-L37

DevDengChao avatar Aug 06 '22 06:08 DevDengChao

You can do the following

import request, { Response } from 'supertest';
type SuperTestResponse<T> = Omit<Response, 'body'> & { body: T };
const getTicketResponse: SuperTestResponse<PostGetTicketResponseBody> = await request(app).post('/get-ticket').send();

But how to type send()?

To me it seems this no-unnecessary-generics linting rule does not make that much sense. Doesn't look to be unnecessary to me.

Currently I'm working arount the problem like this

const payTicketResponse: SuperTestResponse<PostPayTicketResponseBody> = await request(app).post('/pay-ticket').send((() => {
	const requestBody: PostPayTicketRequestBody = {
		barCode: getTicketResponse.body.ticket.barCode,
		paymentMethod,
	};
	return requestBody;
})());

iiinnniii avatar Mar 09 '23 12:03 iiinnniii

Any news on this topic? I think it would be very useful

ivanrodriguezfernandez avatar Apr 07 '24 08:04 ivanrodriguezfernandez