如何定义含固定成员与动态成员的TypeScript类型别名?
TypeScript递归路由组类型定义方案
原代码的问题
你写的类型存在冲突:ResourceRouteGroupBase里的固定键(比如list、view)是string | undefined类型,但交叉的索引签名要求所有字符串键的类型都是ResourceRouteGroupBase,这两个类型不兼容,TypeScript会直接抛出类型错误。
正确实现方式
要实现**包含固定可选string键、同时允许任意额外键(值为同结构递归类型)**的需求,需要定义递归类型,并确保固定键的类型落在索引签名的允许范围内:
type ResourceRouteGroup = { // 固定可选键,类型为string list?: string; view?: string; edit?: string; create?: string; delete?: string; } & { // 任意额外字符串键,值为当前类型的递归结构(支持嵌套) [key: string]: ResourceRouteGroup | string | undefined; };
说明
- 固定键的
string | undefined类型属于索引签名允许的类型范围,不会触发类型冲突。 - 额外键可以是任意字符串,值既可以是嵌套的同结构路由组,也可以是普通字符串(按需使用)。
测试用例
const group: ResourceRouteGroup = { list: '/items', view: '/items/:id', emailRouteGroup: { list: '/emails', create: '/emails/new' }, userRouteGroup: { edit: '/users/:id/edit', detailGroup: { view: '/users/:id/detail' } } };
如果你的需求是额外键的值必须和固定键一致为string类型,那类型定义更简洁:
type ResourceRouteGroupBase = { list?: string; view?: string; edit?: string; create?: string; delete?: string; }; // 交叉固定键结构和任意string键类型 type ResourceRouteGroup = ResourceRouteGroupBase & Record<string, string | undefined>;
对应示例
const group: ResourceRouteGroup = { list: '/items', view: '/items/:id', email: '/emails', userProfile: '/users/profile' };
内容的提问来源于stack exchange,提问作者VarJohn
相关产品推荐
相关产品推荐

