- To summary the question, I'm asking that is unioning type inside generic and outside generic makes different type.
I'm making API server with express and typescript, and I made wrapper function because return type is formed.
The wrapper function calles this Handler.
export type Handler = (req: Request,
res?: express.Response,
next?: express.NextFunction) => (Response<any> | Promise<boolean>)
If handler returns object, wrapper response with this value. And if handler returns boolean, it does another action like calling next router.
Response is formed like this:
type Response<T> = Promise<ResponseSuccess<T> | ResponseError<T>>;
export type ResponseSuccess<T> = {
data: T
}
export type ResponseError<T> = {
error: string
code: number
data?: T
}
And I made auth handler like this:
export const auth = (permission?: Object): Handler => {
return async (req, res) => {
if (!req.auth) return {error: 'Authorization required', code: 401};
if (typeof permission === 'object') {
for (let key in permission) {
if (req.auth.permission[key] !== permission[key]) return {error: 'Permission denied', code: 403};
}
}
return false;
}
}
I thinked that Response<any> | Promise<boolean> becomes Promise<ResponseSuccess<T> | ResponseError<T>> | Promise<boolean>, and it becomes Promise<ResponseSuccess<T> | ResponseError<T> | boolean>. And auth returns ResponseError or false, so I thinked it makes sense.
But the error occurs when I tries to build it:
error TS2322: Type '(req: Request, res: Response<any, Record<string, any>>) => Promise<false | { error: string; code: number; }>' is not assignable to type 'Handler'.
Type 'Promise<false | { error: string; code: number; }>' is not assignable to type 'Promise<boolean> | Resp<any>'.
Type 'Promise<false | { error: string; code: number; }>' is not assignable to type 'Promise<boolean>'.
Type 'false | { error: string; code: number; }' is not assignable to type 'boolean'.
Type '{ error: string; code: number; }' is not assignable to type 'boolean'.
41 return async (req, res) => {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
42 if (!req.auth) return {error: 'Authorization required', code: 401};
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
48 return false;
~~~~~~~~~~~~~~~~~~~~~
49 }
The error disappears when I remove return false;.
What is the problem? Is unioning inside generic and outside generic makes different result? Or there is another error I didn't found?