[英]Possible to infer keys of a nested object for argument type?
想輸入一個函數,卻無法計算出一個參數。
我有多個對象存儲允許的角色數組,然后通過幫助函數的路由/屏幕將它們命名為一個對象。
該函數將獲取屏幕的密鑰,然后檢查該特定權限對象下的哪個密鑰: 目前我的keyof typeof getAuthPermissions | keyof typeof getUserPermissions
union of keyof typeof getAuthPermissions | keyof typeof getUserPermissions
當使用像checkUserPermission('user', '<all-keys>')
這樣的函數時, 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;
}
這可能嗎? 我知道獲取嵌套鍵可能非常棘手,但我希望從傳入的參數中推斷出這應該是可能的? 謝謝!
請注意,您所建議的, checkUserPermission<T extends Screens>(screen: T, permissionToCheck: keyof typeof allPermissions[T]) {}
這工作得很好。
但是,您遇到了類型錯誤,其中allPermissions[screen][permissionToCheck]
不確定這個表達式: 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'],
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.