I use a little utility/wrapper function for functions related to database operations. It should take a specific function fn with the type Promise<PromiseReturnType<GENERIC>>, then do some stuff (here: checking for connection) before executing it:
// File `A.ts`
type PromiseReturnType<T = undefined> = {success: boolean, response: T }
const DatabaseOperation = <Fn extends (...args: any) => Promise<PromiseReturnType<Data>>, Data>(fn: (...args: any) => Promise<PromiseReturnType<Data>>) => {
return async function (...args: Parameters<Fn>): Promise<PromiseReturnType<Data>> {
if (!isConnected) return Promise.reject({ success: false, response: new Error("Not connected to the Database!") })
return await fn(...args)
}
}
Then I use it like:
// File `B.ts`
const dbOperation = async (myArg: number): Promise<PromiseReturnType<string> => {
return Promise.resolve({ success: true, response: `hello world ${myArg}` })
}
export default DatabaseOperation<typeof dbOperation, string>(dbOperation)
It works fine except the return type can not be inferred. It will be Promise<any> except Promise<PromiseReturnType<string>>.
Using that newly wrapped function will look like this:
import dbOperation from "B.ts"
(function () {
await dbOperation() // Type: dbOperation(myArg: number): Promise<any>
})()
Any suggestions on how to solve this or implement this better in general?
Appreciate your help, thanks.
You were almost there:
declare var isConnected: boolean;
type PromiseReturnType<T = undefined> = { success: boolean, response: T }
const DatabaseOperation = <Data, Fn extends (...args: any[]) => Promise<PromiseReturnType<Data>>,>(fn: (...args: any[]) => Promise<PromiseReturnType<Data>>) => {
return async function (...args: Parameters<Fn>): Promise<PromiseReturnType<Data>> {
if (!isConnected) return Promise.reject({ success: false, response: new Error("Not connected to the Database!") })
return await fn(...args)
}
}
const dbOperation = (myArg: number): Promise<PromiseReturnType<string>> =>
Promise.resolve({ success: true, response: `hello world ${myArg}` })
const fn = DatabaseOperation(dbOperation)
const result = fn(42) // Promise<PromiseReturnType<string>>
You should have to made ...args an array any[] instead of just any