希望输入一个函数,但不能计算出一个参数。
我有多个对象,这些对象存储了允许的角色数组,然后通过它们的辅助功能的路径/屏幕在一个对象下命名。
该函数将获取屏幕上的键,然后再检查该特定权限对象下的哪个键:当前,使用以下功能时,keyof typeof getAuthPermissions | keyof typeof getUserPermissions
的并集显然会返回所有键
checkUserPermission('user', '<all-keys>')
但是,我只想从传递给函数的任何屏幕推断出按键:
所有相关代码:
const userGroups = ['Manager', 'Reporting', 'Payments', 'Support'] as const;
type UserGroup = typeof userGroups[number];
const getUserPermissions = {
userControls: ['Manager', 'Support', 'Payments'],
wallet: ['Manager', 'Support']
};
const getAuthPermissions = {
logoutUser: ['Manager'],
extendUserBonus: ['Manager', 'Support']
}
// ... a fair few more.
const allPermissions = {
user: getUserPermissions,
auth: getAuthPermissions
// ...
}
type Screens = keyof typeof allPermissions;
function checkUserPermission(
screen: Screens,
userRoles: UserGroup[],
// this should be the keys for whichever screen was passed in, (eg. keyof typeof allPermissions[typeof screen]?)
permissionToCheck: keyof typeof getAuthPermissions | keyof typeof getUserPermissions // returns ALL keys. want to infer just from screen passed in
): boolean {
for (const role of userRoles) {
if (allPermissions[screen][permissionToCheck].includes(role)) {
return true;
}
}
return false;
}
这可能吗?我知道获取嵌套键可能会非常棘手,但是我希望通过传递的参数推断这应该可行吗? 谢谢!
答案 0 :(得分:2)
请注意,您的建议checkUserPermission<T extends Screens>(screen: T, permissionToCheck: keyof typeof allPermissions[T]) {}
可以正常工作。
但是,您遇到类型错误,其中typescript不确定allPermissions[screen][permissionToCheck]
这个表达式实际上是一个数组,尽管我认为它在理论上应该能够弄清楚。
如果您进行一些看起来很邪恶的打字,则可以使所有工作正常进行:
function checkUserPermission<T extends Screens>(
screen: T,
userRoles: UserGroup[],
permissionToCheck: keyof typeof allPermissions[T]
): boolean {
for (const role of userRoles) {
const roles = allPermissions[screen][permissionToCheck] as unknown as UserGroup[]
if (roles.includes(role)) {
return true;
}
}
return false;
}
另一种选择:
以不同的方式定义getAuthPermissions和getUserPermissions,但是,这会失去某些类型的特异性,因此请谨慎使用:
const getUserPermissions: Record<string, UserGroup[]> = {
userControls: ['Manager', 'Support', 'Payments'],
wallet: ['Manager', 'Support'],
}
const getAuthPermissions: Record<string, UserGroup[]> = {
logoutUser: ['Manager'],
extendUserBonus: ['Manager', 'Support'],
}