简体   繁体   English

Typescript:为 JSON 嵌套对象定义

[英]Typescript: Define for JSON nested object

I have a nested json object and define a interface for it我有一个嵌套的 json 对象并为它定义了一个接口

interface Menu {
    [key: string]: string[] | Menu;
}

const menuOnlyForRoles: Menu = {
    site: {
        only: [],
        category: {
            only: ['manager', 'head', 'lead'],
        },
        'floor-section': {
            only: ['head', 'lead'],
        },
    },
};

But when I use it.但是当我使用它时。 It appear a warning.它出现一个警告。

const menuPermissionForKey = menuOnlyForRoles.site || { only: [] };
const rolesCanAccessMenu= menuPermissionForKey.only || [];
                                               ▔▔▔▔
     any
     Property 'only' does not exist on type 'Menu | string[]'.
       Property 'only' does not exist on type 'string[]'

What did I do wrong or missing?我做错了什么或遗漏了什么?

You didn't do anything wrong per se.你本身没有做错任何事。 TypeScript just cannot infer whether your menuPermissionForKey is a Menu object or a string array. TypeScript 无法推断您的menuPermissionForKeyMenu对象还是string数组。

Ideally, you'd define your Menu type more strictly.理想情况下,您应该更严格地定义Menu类型。 Barring that, you can create a type predicate :除此之外,您可以创建一个类型谓词

interface Menu {
    [key: string]: string[] | Menu;
}

const menuOnlyForRoles: Menu = {
    site: {
        only: [],
        category: {
            only: ['manager', 'head', 'lead'],
        },
        'floor-section': {
            only: ['head', 'lead'],
        },
    },
};

function isMenu(data: Menu | string[]): data is Menu {
    return !Array.isArray(data);
}

const menuPermissionForKey = menuOnlyForRoles.site || { only: [] };
const rolesCanAccessMenu= isMenu(menuPermissionForKey)
                              ? menuPermissionForKey.only || []
                              : [];

Playground link 游乐场链接


Alternatively, if you're dealing with static data that is known at compile-time, you can use a const assertion , optionally with the satisfies operator to enforce type-checking at edit time:或者,如果您正在处理在编译时已知的静态数据,则可以使用const assertion ,可以选择使用satisfies运算符在编辑时强制执行类型检查:

interface Menu {
    [key: string]: readonly string[] | Menu;
}

const menuOnlyForRoles = {
    site: {
        only: [],
        category: {
            only: ['manager', 'head', 'lead'],
        },
        'floor-section': {
            only: ['head', 'lead'],
        },
    },
} as const satisfies Menu;

const menuPermissionForKey = menuOnlyForRoles.site || { only: [] };
const rolesCanAccessMenu = menuPermissionForKey.only || [];

Playground link 游乐场链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM