如何在TypeScript中限制递归类型的嵌套层级?
如何限制TypeScript递归菜单类型的嵌套层级?
你当前定义的递归菜单接口会允许无限层级的嵌套,要固定限制嵌套层数(比如2层),可以通过泛型递归递减的方式实现,既灵活又易于维护:
实现步骤
- 先定义不含子菜单的基础菜单属性类型
- 用泛型创建带层级限制的菜单类型,通过层级参数递减来控制子菜单的存在权限
// 基础菜单核心属性 type BaseMenuItem = { name: string; path: string; }; // 带层级限制的菜单类型:Level表示允许的子菜单嵌套层数 type MenuItem<Level extends number> = BaseMenuItem & ( // 层级为0时,不允许存在subMenu Level extends 0 ? { subMenu?: never } // 层级大于0时,子菜单的允许嵌套层数减1 : { subMenu?: MenuItem<Level - 1>[] } ); // 定义2层结构的菜单类型(顶层为第1层,子菜单为第2层,再深层级不允许) type IMenuItem = MenuItem<1>;
验证效果
符合层级要求的代码(正常运行)
const menu: IMenuItem[] = [ { name: 'Dashboard', path: '/' }, { name: 'Reports', path: '/reports' }, { name: 'Accounts', path: '/', subMenu: [ { name: 'All', path: '/accounts' }, { name: 'Create', path: '/accounts/create' }, ], }, { name: 'Settings', path: '/settings' }, ];
超过层级限制的代码(触发TypeScript错误)
// 报错:子菜单的subMenu属性不符合类型约束 const menuAlt: IMenuItem[] = [ { name: 'Dashboard', path: '/' }, { name: 'Reports', path: '/reports' }, { name: 'Accounts', path: '/', subMenu: [ { name: 'All', path: '/accounts' }, { name: 'Create', path: '/accounts/create', // 此处不允许存在第3层subMenu subMenu: [ { name: 'admin', path: '/accounts/create-admin' }, { name: 'client', path: '/accounts/create-admin' }, ], }, ], }, { name: 'Settings', path: '/settings' }, ];
方案优势
- 灵活性高:如果需要调整层级(比如改成3层),只需要把
MenuItem<1>改成MenuItem<2>即可,无需修改类型结构 - 可读性强:泛型参数直观表示允许的嵌套层数,代码逻辑清晰
- 维护成本低:相比手动嵌套多层Record类型,泛型递归的方式避免了重复代码
内容的提问来源于stack exchange,提问作者iamcastelli
相关产品推荐
相关产品推荐

