如何在不使用@ts-ignore的情况下动态访问Prisma模型?
优雅映射Prisma模型并移除@ts-ignore的TypeScript解决方案
你可以通过TypeScript的类型收窄和常量断言解决这个问题,既保留映射表的简洁性,又不需要忽略类型检查。
核心思路
- 给游戏映射表添加
as const断言,让TypeScript保留每个键对应的具体Prisma模型类型,避免类型拓宽。 - 基于映射表的键生成合法游戏标识类型,明确允许的取值范围。
- 通过类型守卫或断言,让TypeScript识别校验后的
game参数属于合法键类型,从而正确推断模型类型。
优化后的代码示例
方式一:类型断言快速实现
const { game, id } = request.params as { game: string; id: string }; // 定义游戏到Prisma模型的映射,用as const锁定类型 const gameMap = { 'd3': prisma.d3Profile, // 新增游戏直接添加键值对即可 } as const; // 定义合法的游戏key类型 type GameKey = keyof typeof gameMap; // 校验游戏合法性 if (!Object.keys(gameMap).includes(game)) { return { error: 'unknown game' }; } // 类型断言后无需@ts-ignore,TypeScript能正确识别模型类型 const profile = await gameMap[game as GameKey].findUnique({ where: { id: parseInt(id) } }); return profile ? profile : { error: 'profile not found' };
方式二:自定义类型守卫(更严谨)
如果想让类型收窄更自动化,可自定义类型守卫函数:
const { game, id } = request.params as { game: string; id: string }; const gameMap = { 'd3': prisma.d3Profile, } as const; type GameKey = keyof typeof gameMap; // 自定义类型守卫,校验值是否为合法游戏key function isGameKey(value: string): value is GameKey { return Object.keys(gameMap).includes(value); } // 校验时自动完成类型收窄 if (!isGameKey(game)) { return { error: 'unknown game' }; } // 此时game已被自动识别为GameKey类型,直接调用方法即可 const profile = await gameMap[game].findUnique({ where: { id: parseInt(id) } }); return profile ? profile : { error: 'profile not found' };
关键说明
as const:强制TypeScript将映射表的键和值视为字面量类型,而非宽泛的string或通用Prisma模型类型,确保每个键对应的模型类型精准。keyof typeof gameMap:自动生成合法游戏标识的类型,后续新增游戏时无需手动修改类型定义,维护更方便。- 类型守卫:让TypeScript在通过校验后自动将
game的类型收窄为合法键类型,避免手动断言,代码更安全。
内容的提问来源于stack exchange,提问作者thecodeassassin
相关产品推荐
相关产品推荐

