I'm replicating the ts code in the home page:
import { setupWorker, rest } from 'msw'
interface LoginBody {
username: string
}
interface LoginResponse {
username: string
firstName: string
}
const worker = setupWorker(
rest.post<LoginBody, LoginResponse>('/login', (req, res, ctx) => {
const { username } = req.body
return res(
ctx.json({
username,
firstName: 'John'
})
)
}),
)
worker.start()
But it won't compile saying
TypeScript error in /project/src/integration-tests/mocks/handlers.ts(24,7):
Argument of type 'ResponseTransformer<string>' is not assignable to parameter of type 'ResponseTransformer<LoginResponse>'.
Types of parameters 'res' and 'res' are incompatible.
Type 'MockedResponse<LoginResponse>' is not assignable to type 'MockedResponse<string>'.
Type 'LoginResponse' is not assignable to type 'string'. TS2345
22 | const { username } = req.body
23 | return res(
> 24 | ctx.json({
| ^
25 | username,
26 | firstName: 'John'
27 | })
msw: ^0.24.2nodejs: v12.18.0npm: 6.14.4Seems like this is a regression of #468.
I'm not sure which way we want/should go with this... using ctx.json returns a string (which is correct), but you lose some type safety with it. I wanted to suggest having a typed ctx.json, but it seems @kettanaito already thought of this 馃檪
If my thinking is correct, the example code should look like this:
import { setupWorker, rest } from 'msw'
interface LoginBody {
username: string
}
interface LoginResponse {
username: string
firstName: string
}
const worker = setupWorker(
rest.post<LoginBody>('/login', (req, res, ctx) => {
const { username } = req.body
return res(
ctx.json<LoginResponse>({
username,
firstName: 'John',
}),
)
}),
)
worker.start()
If that's the case, do you want to file a Pull Request for the docs @haikyuu ?
Thanks for looking into it, @timdeschryver. Do I understand it correctly that type inference is lost because ctx.json returns a string? 馃 The intention is to infer the type given to rest.post generic.
@timdeschryver thanks for your suggestion. It does work this way but it's no different than adding a @ts-ignore IMHO. What if I have multiple conditionals? Should I add the typing to each ctx.json call? It will be error prone and repetitive.
Using generics would probably allow ctx.json to pick the type from .post. So I believe this is a bug rather than something we need to update the docs for.
I downgraded to 0.23.0 for now. It's working as expected
Thanks for looking into it, @timdeschryver. Do I understand it correctly that type inference is lost because
ctx.jsonreturns a string? 馃 The intention is to infer the type given torest.postgeneric.
Yes right, because now the json function will return a string instead of an object of type BodyType.
As @marcosvega91 confirmed, it's because the json function returns a string.
I'm not very familiar with the codebase, but I suppose this can be fixed by changing the argument type of json function to ctx.json(ResponseBodyType) by taking ResponseBodyType from the types given to the generics of get, post ...
Most helpful comment
Yes right, because now the
jsonfunction will return a string instead of an object of typeBodyType.