You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不使用@ts-ignore的情况下动态访问Prisma模型?

优雅映射Prisma模型并移除@ts-ignore的TypeScript解决方案

你可以通过TypeScript的类型收窄和常量断言解决这个问题,既保留映射表的简洁性,又不需要忽略类型检查。

核心思路

  1. 给游戏映射表添加as const断言,让TypeScript保留每个键对应的具体Prisma模型类型,避免类型拓宽。
  2. 基于映射表的键生成合法游戏标识类型,明确允许的取值范围。
  3. 通过类型守卫或断言,让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 06:55:15