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

如何让Prisma的include关联查询结果兼容TypeScript类型?

Prisma关联查询的TypeScript类型兼容问题解决

问题描述

执行带include的关联查询:

await prisma.song.findMany({
    include: {
      artist: true
    }
})

Prisma会将关联的artist数据添加到song.artist字段,但默认生成的Song TypeScript类型仅包含模型的直接字段,没有.artist属性,导致报错:

Property 'artist' does not exist on type {type definition for song}

解决方案

完全可以生成包含关联扩展的类型,以下是两种常用方案:

1. 使用Prisma自动推导的嵌套类型(推荐)

Prisma会根据你的查询配置自动生成对应的类型,通过Prisma.ModelNameGetPayload工具类型就能获取包含关联的完整类型:

import { Prisma } from '@prisma/client';

// 定义查询的包含配置并标记为常量,让TypeScript保留类型细节
const includeArtistConfig = { include: { artist: true } } as const;
// 推导包含artist后的Song类型
type SongWithArtist = Prisma.SongGetPayload<typeof includeArtistConfig>;

// 直接使用推导后的类型
const songs: SongWithArtist[] = await prisma.song.findMany(includeArtistConfig);
// 此时访问song.artist完全符合TypeScript类型规范
songs.forEach(song => console.log(song.artist.name));

2. 手动扩展类型(适合特殊场景)

如果需要自定义类型结构,可以手动扩展基础Song类型:

import { Song, Artist } from '@prisma/client';

// 合并基础Song类型和关联的Artist类型
type SongWithArtist = Song & {
  artist: Artist;
};

// 查询时通过类型断言指定结果类型
const songs = await prisma.song.findMany({ include: { artist: true } }) as SongWithArtist[];

这种方式需要手动维护类型同步,当模型字段或关联关系变更时容易出错,仅在自动推导无法满足需求时使用。

进阶:封装复用带类型的查询

如果某个关联查询频繁使用,可以通过Prisma客户端扩展封装成方法,固化类型:

import { PrismaClient, Prisma } from '@prisma/client';

const prisma = new PrismaClient().$extends({
  model: {
    song: {
      async findManyWithArtist() {
        return prisma.song.findMany({ include: { artist: true } }) as Prisma.SongGetPayload<{ include: { artist: true } }>[];
      }
    }
  }
});

// 调用封装方法时直接获得正确类型
const songs = await prisma.song.findManyWithArtist();

内容的提问来源于stack exchange,提问作者Nathan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 00:46:10