Another way to wrap HOC function with typescript check
Closed this issue · 1 comments
Mayvis commented
In the course, I got an error Parameter 'handler' implicitly has an 'any' type.
if I don't give handler type with any.
Below is my solution, hope this can help. ;)
// lib/auth.ts
export const validateRoute = (
handler: any // I have to give type any, and the error will disappear
) => {
return async (
req: NextApiRequest,
res: NextApiResponse
): Promise<void> => {
const { SPOTIFY_ACCESS_TOKEN: token } = req.cookies
if (token) {
let user
try {
const { id } = verify(token, 'hello') as JwtPayload
user = await prisma.user.findUnique({
where: { id },
})
if (!user) {
throw new Error('Not real user')
}
} catch (e) {
return res.status(401).json({ error: 'Not authorized' })
}
return handler(req, res, user)
}
return res.status(401).json({ error: 'Not authorized' })
}
}
So I wrapped user to req method, tweak a little bit code, and this work very well. ;)
// lib/auth.ts
import { JwtPayload, verify } from 'jsonwebtoken'
import type { NextApiRequest, NextApiResponse } from 'next'
import prisma from './prisma'
export type NextApiRequestWithUser = NextApiRequest & { user: JwtPayload } // need to export this to me.ts
// higher order function wrapper for validateRoute
export const validateRoute = (
handler: (req: NextApiRequestWithUser, res: NextApiResponse) => void
) => {
return async (
req: NextApiRequestWithUser,
res: NextApiResponse
): Promise<void> => {
const { SPOTIFY_ACCESS_TOKEN: token } = req.cookies
if (token) {
let user
try {
const { id } = verify(token, 'hello') as JwtPayload
user = await prisma.user.findUnique({
where: { id },
})
if (!user) {
throw new Error('Not real user')
}
} catch (e) {
return res.status(401).json({ error: 'Not authorized' })
}
req.user = user // register user to req
return handler(req, res)
}
return res.status(401).json({ error: 'Not authorized' })
}
}
// pages/api/me.ts
import { NextApiResponse } from 'next'
import { NextApiRequestWithUser, validateRoute } from '../../lib/auth'
export default validateRoute(
(req: NextApiRequestWithUser, res: NextApiResponse) => {
res.json(req.user)
}
)
eslint will show an 'no-unused-vars' error. Below is my solution.
ref: https://stackoverflow.com/questions/55807329/why-eslint-throws-no-unused-vars-for-typescript-interface
// eslint.js
rules: {
'@typescript-eslint/no-unused-vars': [
2,
{
args: 'none',
},
],
}
nitin-dixit commented
I did it like this export const validateRoute = (handler: Function) => {...}