在为数据定义适当的types
时遇到问题。我有一个包含以下数据的对象数组,我的任务是根据数据的结构给出适当的types
。
export const DashboardSections = [
{
name: 'Dashboard',
sectionItems: [
{
title: 'Dashboard',
icon: 'FaHome',
path: adminUrl,
type: 'link',
active: true,
children: [],
},
{
title: 'Products',
icon: 'FaBox',
path: `${adminUrl}/products`,
type: 'sub',
active: false,
children: [
{
path: `${adminUrl}/products`,
title: 'Products',
type: 'link',
active: false,
children: [],
},
{
path: `${adminUrl}/categories`,
title: 'Categories',
type: 'link',
active: false,
children: [],
},
// Tags are more specific (describe your posts in more detail)
{
path: `${adminUrl}/tags`,
title: 'Tags',
type: 'link',
active: false,
children: [],
},
{
path: `${adminUrl}/attributes`,
title: 'Attributes',
type: 'link',
active: false,
children: [],
},
],
},
{
title: 'Menus',
icon: 'FaThLarge',
path: `${adminUrl}/menus`,
type: 'link',
active: false,
children: [],
},
],
},
{
name: 'System',
sectionItems: [
{
title: 'Appearance',
icon: 'FaPalette',
path: `${adminUrl}/sliders`,
type: 'sub',
active: false,
children: [],
},
],
},
];
我认为根项目之后的数据具有递归结构。所以我已经这样定义types
。
type link = 'link' | 'sub';
type rootDashItem = {
/** Title of the root item */
title: string;
/** Only root item could contain a svg **/
icon: string;
/** Path of the root item */
path: string;
/** Root item could be a 'link' i.e. don't have any children(empty array) or 'sub' means has array of children. */
type: link;
/** Item would be active or not */
active: boolean;
/** Contain array of sub items */
children: subDashItem[];
};
type subDashItem = {
title: string;
path: string;
type: link;
active: boolean;
children: subDashItem[];
};
export type dashSection = {
name: string;
sectionItems: rootDashItem[];
};
但是当我尝试在其他地方重用type
const items = DashboardSections.map((section: dashSection ) => {
return section.sectionItems.filter((item: rootDashItem) => {
if (item.active) {
return {...item, section: section.name}
}
});
Linter在DashboardSections.map((section: dashSection )
行上引发错误。
Error:(130, 37) TS2345: Argument of type '(section: dashSection) => rootDashItem[]' is not assignable to parameter of type '(value: { name: string; sectionItems: { title: string; icon: IconType; path: string; type: string; active: boolean; children: { path: string; title: string; type: string; active: boolean; children: never[]; }[]; }[]; }, index: number, array: { ...; }[]) => rootDashItem[]'.
Types of parameters 'section' and 'value' are incompatible.
Type '{ name: string; sectionItems: { title: string; icon: IconType; path: string; type: string; active: boolean; children: { path: string; title: string; type: string; active: boolean; children: never[]; }[]; }[]; }' is not assignable to type 'dashSection'.
Types of property 'sectionItems' are incompatible.
Type '{ title: string; icon: IconType; path: string; type: string; active: boolean; children: { path: string; title: string; type: string; active: boolean; children: never[]; }[]; }[]' is not assignable to type 'rootDashItem[]'.
Type '{ title: string; icon: IconType; path: string; type: string; active: boolean; children: { path: string; title: string; type: string; active: boolean; children: never[]; }[]; }' is not assignable to type 'rootDashItem'.
Types of property 'type' are incompatible.
Type 'string' is not assignable to type 'link'.
我做错了什么?为递归结构定义类型的更好方法是什么?
完整代码:
const adminUrl = "http://localhost:3000/admin";
//#region Types
type link = 'link' | 'sub';
type subDashItem = {
title: string;
path: string;
type: link;
active: boolean;
children: subDashItem[];
};
type rootDashItem = {
/** Title of the root item */
title: string;
/** Only root item could contain a svg **/
icon: string;
/** Path of the root item */
path: string;
/** Root item could be a 'link' i.e. don't have any children(empty array) or 'sub' means has array of children. */
type: link;
/** Item would be active or not */
active: boolean;
/** Contain array of sub items */
children: subDashItem[];
};
export type dashSection = {
name: string;
sectionItems: rootDashItem[];
};
//#endregion Types
//#region Item Structure
export const DashboardSections = [
{
name: 'Dashboard',
sectionItems: [
{
title: 'Dashboard',
icon: '',
path: adminUrl,
type: 'link',
active: true,
children: [],
},
{
title: 'Products',
icon: '',
path: `${adminUrl}/products`,
type: 'sub',
active: false,
children: [
{
path: `${adminUrl}/products`,
title: 'Products',
type: 'link',
active: false,
children: [],
},
{
path: `${adminUrl}/categories`,
title: 'Categories',
type: 'link',
active: false,
children: [],
},
// Tags are more specific (describe your posts in more detail)
{
path: `${adminUrl}/tags`,
title: 'Tags',
type: 'link',
active: false,
children: [],
},
{
path: `${adminUrl}/attributes`,
title: 'Attributes',
type: 'link',
active: false,
children: [],
},
],
},
{
title: 'Menus',
icon: '',
path: `${adminUrl}/menus`,
type: 'link',
active: false,
children: [],
},
],
},
{
name: 'System',
sectionItems: [
{
title: 'Appearance',
icon: '',
path: `${adminUrl}/sliders`,
type: 'sub',
active: false,
children: [],
},
],
},
];
//#endregion Item Structure
// Challenge is to take those root items which are active with its corresponding section title
const items = DashboardSections.map((section: dashSection ) => {
return section.sectionItems.filter((item: rootDashItem) => {
if (item.active) {
return {...item, section: section.name}
}
});
});
console.log(items);
答案 0 :(得分:1)
您只需要注释DashboardSections
的类型:
export const DashboardSections: Array<dashSection> = [/*...*/]
然后在section.sectionItems.filter((item: rootDashItem) => ...
中修复过滤器回调。过滤器函数应返回boolean
。因此,您可能想按item.active
进行过滤,然后再次按map
进行过滤,以根据需要转换项目。