I have a nested json object and define a interface for it
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.
Ideally, you'd define your Menu type more strictly. 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:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With