Skip to content

Instantly share code, notes, and snippets.

@rahulballal
Created October 18, 2022 11:46
Show Gist options
  • Save rahulballal/73e0319fd4a1890f336dfd90139d7e22 to your computer and use it in GitHub Desktop.
Save rahulballal/73e0319fd4a1890f336dfd90139d7e22 to your computer and use it in GitHub Desktop.
Typesafe Express Shit
import Express from 'express'
import { Application, NextFunction, Request, Response } from 'express'
import y from 'yup'
export interface TypedRequest<TBody> extends Request {
body: TBody
}
export interface TypedResponse<TBody> extends Response {
json: (body: TBody) => Response
}
const PostEmailRequestSchema = y.object().shape({
subject: y.string().required(),
to: y.array(y.string()).required(),
cc: y.array(y.string()).optional(),
bcc: y.array(y.string()).optional(),
})
const PostEmailResponseSchema = y.object().shape({
message: y.string().required(),
id: y.string().required(),
})
type PostEmailRequest = {
subject: string
to: string[]
cc?: string[]
bcc?: string[]
}
type PostEmailResponse = { id: string; message: string }
const PostEmailHandler = async (
req: TypedRequest<PostEmailRequest>,
res: TypedResponse<PostEmailResponse>,
next: NextFunction
) => {
const postBody = req.body
const isValid = await PostEmailRequestSchema.isValid(postBody)
if (!isValid) {
res.statusCode = 400
return next()
}
res.statusCode = 201
const response: PostEmailResponse = {
id: new Date().getUTCMilliseconds().toString(),
message: 'Accepted',
}
const isResponseValid = await PostEmailResponseSchema.isValid(response)
if(isResponseValid) {
res.json(response)
return next()
}
throw new Error('This api is shit but typesafe')
}
const router = Express.Router()
router.post('/email', PostEmailHandler)
const emailApp: Application = Express()
emailApp.use(router)
const PORT = 3333
emailApp.listen(PORT, () => `📧 Email API Started on http://localhost:${PORT}`)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment