Type alias 'Permission' circularly references itself

758 Views Asked by At

I am defining a type for my Permissions object which is:

const Permissions = {
    PageManagement: {
        MainPageManagement: {
            ViewPage: 'view-page',
            CreatePage: 'create-page',
            UpdatePage: 'update-page',
            DeletePage: 'delete-page',
            ActivateDeactivatePage: 'activate-deactivate-page',
        },
        PageSectionManagement: {
            ViewPageSection: 'view-page-section',
            CreatePageSection: 'create-page-section',
            UpdatePageSection: 'update-page-section',
            DeletePageSection: 'delete-page-section',
            ActivateDeactivatePageSection: 'activate-deactivate-page-section',
        },
    },
    RoleManagement: {
        ViewRole: 'view-role',
        CreateRole: 'create-role',
        UpdateRole: 'update-role',
        DeleteRole: 'delete-role',
        AssignRole: 'assign-role',
        RemoveRole: 'remove-role',
        ActivateDeactivateRole: 'activate-deactivate-role',
    },
};

As you can see, PageManagement has nested two objects, while RoleManagement doesn't have. I'm trying to create a n-level nested type definition, the one that I've created now is:

type Permission = Record<string, string | Permission>

But it gives this error:

Type alias 'Permission' circularly references itself

Any idea what I'm doing wrong? I'm using TypeScript v4.2.3

2

There are 2 best solutions below

1
On BEST ANSWER

The Record is the source of the problem. It requires a complete type before it can result in a type.

type Permission = { [key: string]: string | Permission }

This will work.

3
On

you can use an interface instead of type.

const permissions: Permission = {
    PageManagement: {
        MainPageManagement: {
            ViewPage: 'view-page',
            CreatePage: 'create-page',
            UpdatePage: 'update-page',
            DeletePage: 'delete-page',
            ActivateDeactivatePage: 'activate-deactivate-page',
        },
        PageSectionManagement: {
            ViewPageSection: 'view-page-section',
            CreatePageSection: 'create-page-section',
            UpdatePageSection: 'update-page-section',
            DeletePageSection: 'delete-page-section',
            ActivateDeactivatePageSection: 'activate-deactivate-page-section',
        },
    },
    RoleManagement: {
        ViewRole: 'view-role',
        CreateRole: 'create-role',
        UpdateRole: 'update-role',
        DeleteRole: 'delete-role',
        AssignRole: 'assign-role',
        RemoveRole: 'remove-role',
        ActivateDeactivateRole: 'activate-deactivate-role',
    },
};

interface Permission {
  [key: string]: string | Permission
}

Also reproduction example