如何将含动态键的JSON对象转换为TypeScript泛型类型?
TypeScript 类型定义方案
针对你提供的带动态键的JSON结构,我们可以通过接口(interface)+ 索引签名/Record工具类型实现类型定义,也可以结合泛型让类型更灵活。以下是具体实现:
1. 定义基础子类型
先抽取出固定结构的子类型:
// 角色类型 interface Role { id: number; slug: string; } // 权限详情类型 interface Permission { id: number; action: string; slug: string; level: string; } // 应用类型(包含动态权限键) interface Application { id: number; slug: string; appName: string; status: string; appType: string; appUrl: string; appIcon: string | null; // 动态权限键:键为任意字符串,值为Permission类型 permissions: Record<string, Permission>; // 也可使用索引签名写法: // permissions: { [permissionSlug: string]: Permission }; }
2. 定义最终用户类型(带动态应用键)
对于applications的动态键,同样用Record或索引签名处理,也可以用泛型指定键的范围(如果提前知道可能的键值):
方式一:通用动态键版本(推荐)
适合不确定具体键值的场景:
interface User { id: number; isSuperAdmin: boolean; firstName: string; lastName: string; email: string; gender: string | null; dob: string | null; photo: string | null; status: string; roles: Role[]; // 动态应用键:键为任意字符串,值为Application类型 applications: Record<string, Application>; // 索引签名写法: // applications: { [appSlug: string]: Application }; }
方式二:泛型版本(适合已知键值的场景)
如果提前知道applications和permissions的可能键,可以用泛型约束让类型更精准:
interface User<AppSlugs extends string, PermSlugs extends string> { id: number; isSuperAdmin: boolean; firstName: string; lastName: string; email: string; gender: string | null; dob: string | null; photo: string | null; status: string; roles: Role[]; applications: Record<AppSlugs, { id: number; slug: AppSlugs; appName: string; status: string; appType: string; appUrl: string; appIcon: string | null; permissions: Record<PermSlugs, Permission>; }>; } // 使用示例:指定已知的应用和权限键 type SpecificUser = User<'application_management' | 'user_management', 'create_application' | 'delete_application' | 'update_application'>;
3. 类型验证测试
你可以用提供的JSON验证类型兼容性:
const userData: User = { "id": 1, "isSuperAdmin": true, "firstName": "Oleksii", "lastName": "", "email": "alexp@point2web.com", "gender": null, "dob": null, "photo": null, "status": "ACTIVE", "roles": [ { "id": 1, "slug": "Head of Department-(Account Management-Network-P2W North America)" }, { "id": 2, "slug": "Team Lead-(Account Management-Network-P2W North America)" }, { "id": 3, "slug": "Employee-(Account Management-Network-P2W North America)" } ], "applications": { "application_management": { "id": 41, "slug": "application_management", "appName": "Application Management", "status": "ACTIVE", "appType": "CODED", "appUrl": "application-management", "appIcon": "http://api.chromosome-studio.com/uploads/applications/application.png", "permissions": { "delete_application": { "id": 3, "action": "Delete Application", "slug": "delete_application", "level": "all" }, "update_application": { "id": 2, "action": "Update Application", "slug": "update_application", "level": "all" }, "create_application": { "id": 1, "action": "Create Application", "slug": "create_application", "level": "all" } } }, "user_management": { "id": 42, "slug": "user_management", "appName": "Application Management", "status": "ACTIVE", "appType": "CODED", "appUrl": "user-management", "appIcon": "http://api.chromosome-studio.com/uploads/applications/users.png", "permissions": { "create_application": { "id": 4, "action": "Create Application", "slug": "create_application", "level": "all" } } } } };
内容的提问来源于stack exchange,提问作者Ramanath
相关产品推荐
相关产品推荐

