typescript - 使用 Prisma 生成的类型作为函数参数类型

标签 typescript prisma

我正在尝试 Prisma ORM,看看有什么可能性。创建模型并生成 PrismaClient 之后,我认为可以使用生成的类型并将它们用于变量和响应类型,但情况似乎并非如此。

...

model Invite {
  id        Int        @id @default(autoincrement())
  gender    Gender
  firstName String     @map("first_name")
  lastName  String     @map("last_name")
  language  Language
  email     String     @unique
  token     String     @unique

  roleId Int  @map("role_id")
  role   Role @relation(fields: [roleId], references: [id])

  organisationId Int          @map("organisation_id")
  organisation   Organisation @relation(fields: [organisationId], references: [id])

  updatedAt DateTime @updatedAt @map("updated_at")
  createdAt DateTime @default(now()) @map("created_at")

  @@map("invites")
}

...

上面我有一个与组织和角色模型相关的邀请模型。在邀请服务文件中,我正在准备所有输入以创建新邀请。

import { Request, Response, NextFunction } from 'express';
import roleRepository from '../repositories/role.repository';
import organisationRepository from '../repositories/organisation.repository';
import generateToken from '../utils/helpers/generateToken';
import inviteRepository from '../repositories/invite.repository';

const createInvite = async (req: Request, res: Response) => {
    const { body } = await validateInput(req);
    const { gender, firstName, lastName, email, language, roleId, organisationId } = body;

    const role = roleRepository.findRoleById(roleId);

    if (!role) {
        throw new Error('Role does not exist');
    }

    const organisation = organisationRepository.findOrganisationById(organisationId);

    if (!organisation) {
        throw new Error('Organisation does not exist');
    }

    const token = generateToken();

    const invite = inviteRepository.createInvite({
        gender,
        firstName,
        lastName,
        email,
        language,
        role: role,
        organisation: organisation,
        token,
    });

    await mailService.sendInviteEmail(invite);

    res.status(201).json({
        message: 'Invite created successfully',
    });
};

inviteRepository 文件的 createInvite 函数中,我尝试使用生成的 Prisma 类型,InviteCreateInput

const createInvite = async (inviteData: Prisma.InviteCreateInput): Promise<Invite> => {
    return db.invite.create({
        data: {
            gender: inviteData.gender,
            firstName: inviteData.firstName,
            lastName: inviteData.lastName,
            language: inviteData.language,
            email: inviteData.email,
            token: inviteData.token,
            role: {
                connect: {
                    id: inviteData.role
                }
            },
            organisation: {
                connect: {
                    id: inviteData.organisation,
                }
            }
        },
    });
};

Prisma recommends this 'safe' way of InputInviteCreateInput 看起来像这样

  export type InviteCreateInput = {
    gender: Gender
    firstName: string
    lastName: string
    language: string
    email: string
    token: string
    updatedAt?: Date | string
    createdAt?: Date | string
    role: RoleCreateNestedOneWithoutInviteInput
    organisation: OrganisationCreateNestedOneWithoutInvitesInput
  }

RoleCreateNestedOneWithoutInviteInput看起来像这样:

  export type RoleCreateNestedOneWithoutInviteInput = {
    create?: XOR<RoleCreateWithoutInviteInput, RoleUncheckedCreateWithoutInviteInput>
    connectOrCreate?: RoleCreateOrConnectWithoutInviteInput
    connect?: RoleWhereUniqueInput
  }

由于此类型需要创建、connectOrCreate 或 connect,因此它似乎无法用作此函数的函数参数类型(还想知道此类型可以在什么方法中使用)。我发现 InviteUncheckedCreateInput 作为可能使用的类型,但由于 Prisma 不建议使用 unchecked 类型,我不确定这是否是一个好方法。

有人有使用 Prisma 类型作为函数参数类型的经验,还是自己创建一个类型更好?

最佳答案

Prisma 认为它“更安全”的原因是他们假设您可能没有检查 roleIdorganizationId (您正在使用 进行检查) findRoleByIdfindOrganizationById

为了性能,我会删除额外的查询 - findRoleByIdfindOrganizationById 并像这样编写中间件:

const createInvite = async (req: Request, res: Response) => {
  const { body } = await validateInput(req);
  const { gender, firstName, lastName, email, language, roleId, organisationId } = body;

  const token = generateToken();

  try {
    const invite = await inviteRepository.createInvite({
      gender,
      firstName,
      lastName,
      email,
      language,
      token,
      role: {
        connect: {
          id: roleId,
        },
      },
      organisation: {
        connect: {
          id: organisationId,
        },
      },
    });
  } catch (error) {
    // handle the errors from no organisationId nor roleId existing
    // next(Error) or something similar
  }

  await mailService.sendInviteEmail(invite);

  res.status(201).json({
    message: 'Invite created successfully',
  });
};

您还可以清理您的 createInvite 函数:

const createInvite = async (data: Prisma.InviteCreateInput): Promise<Invite> => {
  return db.invite.create({
    data,
  });
};

关于typescript - 使用 Prisma 生成的类型作为函数参数类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76714329/

相关文章:

javascript - Angular 7 : Build on prod : Property 'service' is private and only accessible within class "Component"

android - Ionic 2 RC0 和 Angular 2 最新构建 android 错误 (ngc : Error: Error encountered resolving symbol values statically)

typescript - 新的 Nestjs 应用程序上的 Webpack Typescript 错误

sql - Prisma throw 错误 : Ambiguous relation detected

postgresql - 如何在 Prisma ORM 中过滤关系

reactjs - 当我的数据在接下来的 13 年发生更改时,如何重新渲染?

angular - 使用 Angular 中的自定义按钮进行滑动分页/导航

typescript - 更新到 TypeScript 2.4.1 和 Rxjs 5.4.2 后 Observable.forkJoin() TS2322 错误

prisma - 使用 prisma 原始查询插入具有多个字段的多行