I can't get this to work at all:
type Method = {
(pathname: string, handler: CallableFunction): void,
(pathname: string, middleware: CallableFunction[], handler: CallableFunction): void,
}
type Route = {
method: string,
pathname: string,
middleware?: CallableFunction[],
handler: CallableFunction,
}
const routes: Route[] = []
export const get: Method = (param1: string, param2: CallableFunction | CallableFunction[], param3?: CallableFunction) => {
push('GET', param1, param2, param3)
}
export const post: Method = (param1: string, param2: CallableFunction | CallableFunction[], param3?: CallableFunction) => {
push('POST', param1, param2, param3)
}
const push = (method: string, param1: string, param2: CallableFunction | CallableFunction[], param3?: CallableFunction) => {
routes.push({
method: method,
pathname: param1,
middleware: typeof param2 == CallableFunction[] ? param2 : undefined,
handler: typeof param2 == CallableFunction ? param2 : param3,
})
}
Errors:
Type 'CallableFunction | CallableFunction[] | undefined' is not assignable to type 'CallableFunction[] | undefined'. 'CallableFunction' only refers to a type, but is being used as a value here.
How do I check if they are the exact type I am using? Or do I need to be less strict?
Also, is there a way to implement DRY principles so I don't have to repeated the same thing for every route method? See get
, post
, etc.
I tried using typeof param2 == 'function'
but have no idea how to use it for an array of callable functions, etc.
Ideally I want to be able to check the exact types of the overloads...
Edit:
Guess I just have to use as
?:
if (param3) {
routes.push({
method: method,
pathname: param1,
middleware: param2 as CallableFunction[],
handler: param3,
})
}
You can't do a typeof
check against a typescript type, since it doesn't actually exist during runtime. I guess you could do something like this...
type Method = {
(pathname: string, handler: CallableFunction): void,
(pathname: string, middleware: CallableFunction[], handler: CallableFunction): void,
}
type Route = {
method: string,
pathname: string,
middleware?: CallableFunction[],
handler: CallableFunction,
}
const routes: Route[] = []
export const get: Method = (param1: string, param2: CallableFunction | CallableFunction[], param3?: CallableFunction) => {
push('GET', param1, param2, param3)
}
export const post: Method = (param1: string, param2: CallableFunction | CallableFunction[], param3?: CallableFunction) => {
push('POST', param1, param2, param3)
}
const push = (method: string, param1: string, param2: CallableFunction | CallableFunction[], param3?: CallableFunction) => {
const maybeMiddleware = Array.isArray(param2) ? param2 : undefined;
// `param3 ||` is saying if param3 has a value (using falsey check), then honor that since it'll always be a CallableFunction
// next bit `Array.isArray(param2) ? param2[0] : param2` is saying in the event param2 _is_ an array, then we take the first item in the array, otherwise use that CallableFunction
const handler: CallableFunction = param3 || (Array.isArray(param2) ? param2[0] : param2);
routes.push({
method: method,
pathname: param1,
middleware: maybeMiddleware,
handler,
})
}