我的模式看起来像:
schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = "file:./dev.db"
}
model User {
id String @id @default(cuid())
email String? @unique
stripeId String @unique
createdAt DateTime @default(now())
product Product?
@@map("users")
}
model Product {
id String @id @default(cuid())
totalSum Int @default(9700)
user User @relation(fields: [userId], references: [id])
userId String @unique
licenses License[]
@@map("products")
}
model License {
id String @id @default(cuid())
name String @unique
/// no. of licenses generated
total Int @default(1)
/// no. of licenses used
used Int @default(0)
/// stored in cents
product Product? @relation(fields: [productId], references: [id])
productId String?
createdAt DateTime @default(now())
@@map("licenses")
}
我想在执行prisma.license.findMany()
时访问email
字段。我的db
文件看起来像:
db.ts
import { Prisma, License, User } from '@prisma/client'
import { prisma } from './context'
export const getLicenses = async (): Promise<
Array<License & Pick<User, 'email'>> | null | undefined
> => {
const userSelect = Prisma.validator<Prisma.ProductSelect>()({
user: {
select: {
email: true,
},
},
})
const productSelect = Prisma.validator<Prisma.LicenseSelect>()({
product: {
include: userSelect,
},
})
const licenses = await prisma.license.findMany({
orderBy: {
createdAt: 'desc',
},
include: productSelect,
})
const result = licenses.map((license) => {
const email = license.product?.user.email
if (email) {
return {
...license,
email,
}
}
})
return result
}
export const db = {
getLicenses,
}
最后一行return result
给出了这个打字脚本错误:
Type '({ email: string; id: string; name: string; total: number; used: number; productId: string | null; createdAt: Date; product: (Product & { user: { email: string | null; }; }) | null; } | undefined)[]' is not assignable to type '(License & Pick<User, "email">)[]'.
Type '{ email: string; id: string; name: string; total: number; used: number; productId: string | null; createdAt: Date; product: (Product & { user: { email: string | null; }; }) | null; } | undefined' is not assignable to type 'License & Pick<User, "email">'.
Type 'undefined' is not assignable to type 'License & Pick<User, "email">'.
Type 'undefined' is not assignable to type 'License'.ts(2322)
我的模式文件看起来像:
schema.ts
import { db } from './db'
const Query = objectType({
name: 'Query',
definition(t) {
t.list.field('licenses', {
type: 'License',
resolve: async (_, __, ctx) => {
if (!ctx.admin.isLoggedIn) return null
const licenses = await db.getLicenses()
if (licenses) return licenses
return null
},
})
},
})
即使是这个小小的查询也会给我带来很多错误。它曾经在我想使用prisma.license.findMany()
查询所有许可证时工作,但它在我想要email
字段时就开始抛出错误,但格式是平面文件,所以我的输出看起来像:
{
id: string;
name: string;
total: number;
used: number;
productId: string | null;
createdAt: Date;
email: string;
}
我也不希望productId
被发送。我该如何解决这个问题?
我做了一个最小限度的重复→https://github.com/deadcoder0904/prisma-nested-query-email
当您使用Array.map时,如果您没有明确指定每个元素的返回,那么undefined
将进入您的数组——这就是TS错误所指示的。如果(!email(,则map向输出数组返回一个undefined
元素。
从本质上讲,你想要的是过滤那些与电子邮件有关联用户的许可证,然后对其进行映射
实际上,你可以用reduce来代替。https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#replace_.filter.map_with_.reduce
您正在尝试使用Array.map LIKE此Array.reduce功能(它可以取代过滤器/映射(。但是如果使用array.reduce.实现,则undefined无法潜入返回的数组
这里有一个相关的CodeSandbox链接。请注意,esint正在抱怨(期望在箭头函数的末尾返回一个值(。https://codesandbox.io/s/nifty-surf-s8vcg6?file=/src/index.ts
我禁用了db.ts
文件上的TS&然后检查CCD_ 11阵列&发现我需要将email
作为null
而不是undefined
。
一个重要的注意事项是:在License
类型的nexus
配置中,我不得不停止对email
使用nonNull
来停止错误。
工作解决方案已发布在此提交中。它现在工作:(