打字稿 - 我在使用函数的返回值时遇到了麻烦

时间:2017-12-25 04:38:25

标签: javascript arrays typescript

我想迭代一个数组,检查节点是否有较低的节点,以及节点是否与用户的角色兼容。

我以为我可能会使用" for(让someArray进入)"获取数组中节点的每个值但是" someArray"是函数的返回值:

public menuList(): any {
    return [
        // SCHEDULER
        {
            route: ["", "scheduler"],
            name: "scheduler",
            moduleId: PLATFORM.moduleName("../components/scheduler/scheduler"),
            title: "scheduler",
            nav: true,
            settings: {
                icon: "user",
                roles: ["Employee", "Admin"],
                pos: "left"
            }
        },

        // CLIENTS
        {
            route: "clients",
            name: "clients",
            moduleId: PLATFORM.moduleName("../components/clients/clientList/clientList"),
            title: "Clients",
            nav: true,
            settings: {
                icon: "user",
                roles: ["Employee", "Admin"],
                pos: "left",
                nav: [
                    {
                        route: "clients/ClientsList",
                        name: "clientList",
                        moduleId: PLATFORM.moduleName("../components/clients/clientList/clientList"),
                        href: "#clients/clientsList",
                        title: "Client List",
                        settings: {
                            icon: "list",
                            roles: ["Employee", "Admin"],
                        }
                    },
                    {
                        settings: {
                            roles: ["Employee", "Admin"],
                            divider: true,
                        }
                    },
                    {
                        route: "clients/create",
                        name: "newClient",
                        moduleId: PLATFORM.moduleName("../components/clients/newClient/newClient"),
                        href: "#clients/Create",
                        title: "Create Client",
                        settings: {
                            icon: "user",
                            roles: ["Employee", "Admin"],
                        }
                    }
                ]
            }
        },

        // JOBS
        {
            route: "jobs",
            name: "jobs",
            moduleId: PLATFORM.moduleName("../components/jobs/jobsList"),
            title: "Jobs",
            nav: true,
            settings: {
                icon: "list",
                roles: ["Employee", "Admin"],
                pos: "left"
            },
        },

        // ACCOUNTING

        // Accounting - 1st level route WITH SUBROUTES
        {
            route: "accounting",
            name: "accounting",
            moduleId: PLATFORM.moduleName("../components/accounting/ledgerEnquiry/ledgerEnquiry"),
            title: "Accounting",
            nav: true,
            settings: {
                icon: "usd",
                roles: ["Employee", "Admin"],
                pos: "left",
                nav: [
                    {
                        title: "Creditor Cost Invoices",
                        icon: "tasks",
                        nav: true,
                        roles: ["Employee", "Admin"],
                        settings: {
                            nav: [
                                {
                                    title: 'Creditor Payments',
                                    icon: 'usd',
                                    roles: ["Employee", "Admin"],
                                    settings: {
                                        nav: [
                                            {
                                                route: "accounting/creditorCostInvoices/payments/paymentsRegister",
                                                name: "paymentsRegister",
                                                moduleId: PLATFORM.moduleName("../components/accounting/creditorCostInvoices/payments/paymentsRegister/paymentsRegister"),
                                                href: '#accounting/creditorCostInvoices/payments/paymentsRegister',
                                                title: 'Payments Register',
                                                settings: {
                                                    icon: 'list',
                                                    roles: ["Employee", "Admin"]
                                                }
                                            },
                                            {
                                                settings: {
                                                    roles: ["Employee", "Admin"],
                                                    divider: true,
                                                }
                                            },
                                            {
                                                route: "accounting/creditorCostInvoices/payments/creditorPromptPayments",
                                                name: "promptPayments",
                                                moduleId: PLATFORM.moduleName("../components/accounting/creditorCostInvoices/payments/creditorPromptPayments/creditorPromptPayments"),
                                                href: '#accounting/creditorCostInvoices/payments/creditorPromptPayments',
                                                title: 'Creditor Prompt Payments',
                                                settings: {
                                                    icon: 'usd',
                                                    roles: ["Employee", "Admin"]
                                                }
                                            },
                                            {
                                                route: "accounting/creditorCostInvoices/payments/payOutstandingCreditorInvoices",
                                                name: "payments",
                                                moduleId: PLATFORM.moduleName("../components/accounting/creditorCostInvoices/payments/payOutstandingCreditorInvoices/payOutstandingCreditorInvoices"),
                                                href: '#accounting/creditorCostInvoices/payments/payOutstandingCreditorInvoices',
                                                title: 'Pay Outstanding Creditor Invoices',
                                                settings: {
                                                    icon: 'edit',
                                                    roles: ["Employee"/*, "Admin"*/]
                                                }
                                            },
                                        ],
                                    }
                                },
                            ]
                        }
                    },
                ]
            }
        }
    ]
}

Scheduler是一个节点,而client是另一个节点,但客户端有一个包含三个节点的数组。

我想迭代这个并创建一个新数组,如果任何节点不满足角色值,那么该节点被遗漏,同时仍保持原始数组的深度结构。所以在menuList()中如果迭代检查角色设置是否具有" Admin"并且它不会忽略该节点,我得到一个过滤的数组,只有那些具有" Admin"在它。

我做了一个怪物" for loop"嵌套" for循环"试图抓住这个但失败了。

我现在认为我会使用let entry of someArray,但我收到错误:

  

错误TS2349(TS)无法调用类型缺少调用签名的表达式。输入'任何[]'没有兼容的呼叫签名

不知道如何解决这个问题......

是否有一种智能方法可以在保持结构的同时基于role.includes(" Admin")等过滤此数组?

更新

我终于设法让这个工作了,虽然我认为会有更多更简洁的方法。

我采取了在移动到下一个节点之前完全处理每个节点的观点,为此我使用了一个为每个级别调用自身的递归函数。

public userMenu(userName: string, userRole: string): any {
    let finishedRoleCheckedMenu = Array();
    let userMenuElements = Array();
    let returnedElement = {} as any;


    for (const key in this.menuList()) {
        returnedElement = this.processElement(this.menuList()[key], userRole);

        if (returnedElement !== 'undefined') {
            userMenuElements.push(returnedElement);
        }
    }

    for (let count = 0; count < this.routeMenuItems.length; count++) {
        if (!this.routeMenuItems[count].settings.divider) {
            userMenuElements.push(this.routeMenuItems[count]);
        }
    }

    return userMenuElements;
}


processElement(element: any, userRole: string) {
    let testedElement = {} as any;
    let settingsElement = {} as any;
    let navElements = Array();
    let navElement = {} as any;

    if (element.settings.roles.includes(userRole)) {

        for (const key in element) {
            if (key === "settings") {

                for (const settingsKey in element[key]) {
                    if (settingsKey === "nav") {

                        for (const navKey in element[key][settingsKey]) {

                            navElement = this.processElement(element[key][settingsKey][navKey], userRole); // recursive call.

                            if (navElement !== 'undefined') {
                                if (navElement.route) {  // Collect only those elements with routes.
                                    this.routeMenuItems.push(navElement); // For adding the total routes at the end.
                                }
                                navElements.push(navElement);
                            }
                        }
                        if (navElements.length > 0) {

                            settingsElement[settingsKey] = navElements;
                        }
                    } else {
                        settingsElement[settingsKey] = element[key][settingsKey];
                    }
                }
                testedElement[key] = settingsElement;
            } else {
                testedElement[key] = element[key];
            }
        }

        return testedElement;
    } else {
        return 'undefined';
    }
}

1 个答案:

答案 0 :(得分:1)

编译器抱怨调用者代码。特别是无论它计划如何处理返回的数组。原因是因为您已将返回类型指定为“any”。也许返回类型的数组可能更合适。

就过滤数组而言,我认为你是在正确的轨道上,但是你可以通过使用地图或地图/缩小模式来清理代码。