My goal is to create 2 interfaces for accessing the database:
dao
can be used by both admins and regular users, so each function needs anisAdmin:boolean
parameter (e.g.
)updateUser(isAdmin: boolean, returnUser)
daoAsAdmin
, on the other hand, allows methods to be called without theisAdmin
parameter (e.g.updateUser(returnUser)
)
Below is a snippet of code showcasing this:
type User = { name: string }
type DaoAsAdmin = {
updateUser<ReturnUser extends boolean>(
returnUser: ReturnUser
): ReturnUser extends true ? User : string
}
type Dao = {
// injects `isAdmin` as first param of all dao methods
[K in keyof DaoAsAdmin]: (isAdmin: boolean, ...params: Parameters<DaoAsAdmin[K]>) => ReturnType<DaoAsAdmin[K]>
}
// Real code implementation
const dao: Dao = {
updateUser(isAdmin, returnUser) {
throw 'not implemented'
}
}
// Using proxy trick to set isAdmin = true
// as the first param of each dao method
const daoAsAdmin = new Proxy(dao, {
get(target, prop, receiver) {
return function (...params) {
const NEW_PARAMS = [true, ...params]
return target[prop](NEW_PARAMS)
}
},
}) as DaoAsAdmin
// Now, calling updateUser is simplified
const userAsAdmin = daoAsAdmin.updateUser(true) // returns type User
const userStringAsAdmin = daoAsAdmin.updateUser(false) // returns type string
// However, dao functions do not return the expected types
const user = dao.updateUser(false, true) // returns type string | User instead of just User
const userAsStr = dao.updateUser(false, false) // returns type string | User instead of just string
I have attempted various strategies but could not ensure that dao
functions return the correct type. It appears that a combination of Parameters
and ReturnType
is needed, but there are no guidelines on using ReturnType
with specified function parameters.
What modifications should I make to the Dao
type definition to achieve the desired result?
The actual scenario is more complex and necessitates declaring types and constants separately. Please let me know if further clarification is required.