簡體   English   中英

可以推斷參數類型的嵌套對象的鍵嗎?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM