Skip to content

zod-prisma-types

Directory Structure

.
├── package.json
├── prisma
│   ├── generated
│   │   └── zod
│   │       ├── inputTypeSchemas
│   │       │   ├── PostScalarFieldEnumSchema.ts
│   │       │   ├── SortOrderSchema.ts
│   │       │   ├── TransactionIsolationLevelSchema.ts
│   │       │   └── UserScalarFieldEnumSchema.ts
│   │       └── modelSchema
│   │           ├── PostSchema.ts
│   │           └── UserSchema.ts
│   ├── migrations
│   │   ├── *_init
│   │   │   └── migration.sql
│   │   └── migration_lock.toml
│   └── schema.prisma
├── src
│   └── index.ts
└── tsconfig.json
sh
npm install zod-prisma-types --save-dev
prisma
generator client {
  provider = "prisma-client-js"
}

generator zod {
  provider                         = "zod-prisma-types"
  output                           = "./generated/zod" // 出力ディレクトリの指定
  useMultipleFiles                 = true // スキーマを複数ファイルに分割
  writeBarrelFiles                 = false // バレルファイルの生成を無効化
  createInputTypes                 = false // 入力タイプの生成を無効化
  createModelTypes                 = true // モデルタイプの生成を有効化
  addInputTypeValidation           = true // 入力タイプに対するバリデーションの追加
  createOptionalDefaultValuesTypes = true // デフォルト値を持つフィールドをオプショナルに
  createRelationValuesTypes        = true // リレーションフィールドを含むタイプの生成
  createPartialTypes               = true // 全フィールドをオプショナルにしたパーシャルタイプの生成
  useDefaultValidators             = false // Zodのデフォルトバリデータの使用を無効化
}

model User {
  id    Int    @id @default(autoincrement())
  email String @unique
  name  String
  posts Post[]
}

model Post {
  id       Int    @id @default(autoincrement())
  title    String
  content  String
  authorId Int
  author   User   @relation(fields: [authorId], references: [id])
}

Generate

sh
npx prisma generate

Generated Zod

Example

ts
import { z } from 'zod'
import type { UserWithRelations } from './UserSchema'
import type { UserPartialWithRelations } from './UserSchema'
import type { UserOptionalDefaultsWithRelations } from './UserSchema'
import { UserWithRelationsSchema } from './UserSchema'
import { UserPartialWithRelationsSchema } from './UserSchema'
import { UserOptionalDefaultsWithRelationsSchema } from './UserSchema'

/////////////////////////////////////////
// POST SCHEMA
/////////////////////////////////////////

export const PostSchema = z.object({
  id: z.number(),
  title: z.string(),
  content: z.string(),
  authorId: z.number(),
})

export type Post = z.infer<typeof PostSchema>

/////////////////////////////////////////
// POST PARTIAL SCHEMA
/////////////////////////////////////////

export const PostPartialSchema = PostSchema.partial()

export type PostPartial = z.infer<typeof PostPartialSchema>

/////////////////////////////////////////
// POST OPTIONAL DEFAULTS SCHEMA
/////////////////////////////////////////

export const PostOptionalDefaultsSchema = PostSchema.merge(
  z.object({
    id: z.number().optional(),
  }),
)

export type PostOptionalDefaults = z.infer<typeof PostOptionalDefaultsSchema>

/////////////////////////////////////////
// POST RELATION SCHEMA
/////////////////////////////////////////

export type PostRelations = {
  author: UserWithRelations
}

export type PostWithRelations = z.infer<typeof PostSchema> & PostRelations

export const PostWithRelationsSchema: z.ZodType<PostWithRelations> = PostSchema.merge(
  z.object({
    author: z.lazy(() => UserWithRelationsSchema),
  }),
)

/////////////////////////////////////////
// POST OPTIONAL DEFAULTS RELATION SCHEMA
/////////////////////////////////////////

export type PostOptionalDefaultsRelations = {
  author: UserOptionalDefaultsWithRelations
}

export type PostOptionalDefaultsWithRelations = z.infer<typeof PostOptionalDefaultsSchema> &
  PostOptionalDefaultsRelations

export const PostOptionalDefaultsWithRelationsSchema: z.ZodType<PostOptionalDefaultsWithRelations> =
  PostOptionalDefaultsSchema.merge(
    z.object({
      author: z.lazy(() => UserOptionalDefaultsWithRelationsSchema),
    }),
  )

/////////////////////////////////////////
// POST PARTIAL RELATION SCHEMA
/////////////////////////////////////////

export type PostPartialRelations = {
  author?: UserPartialWithRelations
}

export type PostPartialWithRelations = z.infer<typeof PostPartialSchema> & PostPartialRelations

export const PostPartialWithRelationsSchema: z.ZodType<PostPartialWithRelations> = PostPartialSchema.merge(
  z.object({
    author: z.lazy(() => UserPartialWithRelationsSchema),
  }),
).partial()

export type PostOptionalDefaultsWithPartialRelations = z.infer<typeof PostOptionalDefaultsSchema> & PostPartialRelations

export const PostOptionalDefaultsWithPartialRelationsSchema: z.ZodType<PostOptionalDefaultsWithPartialRelations> =
  PostOptionalDefaultsSchema.merge(
    z
      .object({
        author: z.lazy(() => UserPartialWithRelationsSchema),
      })
      .partial(),
  )

export type PostWithPartialRelations = z.infer<typeof PostSchema> & PostPartialRelations

export const PostWithPartialRelationsSchema: z.ZodType<PostWithPartialRelations> = PostSchema.merge(
  z
    .object({
      author: z.lazy(() => UserPartialWithRelationsSchema),
    })
    .partial(),
)

export default PostSchema
ts
import { z } from 'zod'
import type { PostWithRelations } from './PostSchema'
import type { PostPartialWithRelations } from './PostSchema'
import type { PostOptionalDefaultsWithRelations } from './PostSchema'
import { PostWithRelationsSchema } from './PostSchema'
import { PostPartialWithRelationsSchema } from './PostSchema'
import { PostOptionalDefaultsWithRelationsSchema } from './PostSchema'

/////////////////////////////////////////
// USER SCHEMA
/////////////////////////////////////////

export const UserSchema = z.object({
  id: z.number(),
  email: z.string(),
  name: z.string(),
})

export type User = z.infer<typeof UserSchema>

/////////////////////////////////////////
// USER PARTIAL SCHEMA
/////////////////////////////////////////

export const UserPartialSchema = UserSchema.partial()

export type UserPartial = z.infer<typeof UserPartialSchema>

/////////////////////////////////////////
// USER OPTIONAL DEFAULTS SCHEMA
/////////////////////////////////////////

export const UserOptionalDefaultsSchema = UserSchema.merge(
  z.object({
    id: z.number().optional(),
  }),
)

export type UserOptionalDefaults = z.infer<typeof UserOptionalDefaultsSchema>

/////////////////////////////////////////
// USER RELATION SCHEMA
/////////////////////////////////////////

export type UserRelations = {
  posts: PostWithRelations[]
}

export type UserWithRelations = z.infer<typeof UserSchema> & UserRelations

export const UserWithRelationsSchema: z.ZodType<UserWithRelations> = UserSchema.merge(
  z.object({
    posts: z.lazy(() => PostWithRelationsSchema).array(),
  }),
)

/////////////////////////////////////////
// USER OPTIONAL DEFAULTS RELATION SCHEMA
/////////////////////////////////////////

export type UserOptionalDefaultsRelations = {
  posts: PostOptionalDefaultsWithRelations[]
}

export type UserOptionalDefaultsWithRelations = z.infer<typeof UserOptionalDefaultsSchema> &
  UserOptionalDefaultsRelations

export const UserOptionalDefaultsWithRelationsSchema: z.ZodType<UserOptionalDefaultsWithRelations> =
  UserOptionalDefaultsSchema.merge(
    z.object({
      posts: z.lazy(() => PostOptionalDefaultsWithRelationsSchema).array(),
    }),
  )

/////////////////////////////////////////
// USER PARTIAL RELATION SCHEMA
/////////////////////////////////////////

export type UserPartialRelations = {
  posts?: PostPartialWithRelations[]
}

export type UserPartialWithRelations = z.infer<typeof UserPartialSchema> & UserPartialRelations

export const UserPartialWithRelationsSchema: z.ZodType<UserPartialWithRelations> = UserPartialSchema.merge(
  z.object({
    posts: z.lazy(() => PostPartialWithRelationsSchema).array(),
  }),
).partial()

export type UserOptionalDefaultsWithPartialRelations = z.infer<typeof UserOptionalDefaultsSchema> & UserPartialRelations

export const UserOptionalDefaultsWithPartialRelationsSchema: z.ZodType<UserOptionalDefaultsWithPartialRelations> =
  UserOptionalDefaultsSchema.merge(
    z
      .object({
        posts: z.lazy(() => PostPartialWithRelationsSchema).array(),
      })
      .partial(),
  )

export type UserWithPartialRelations = z.infer<typeof UserSchema> & UserPartialRelations

export const UserWithPartialRelationsSchema: z.ZodType<UserWithPartialRelations> = UserSchema.merge(
  z
    .object({
      posts: z.lazy(() => PostPartialWithRelationsSchema).array(),
    })
    .partial(),
)

export default UserSchema

Custom validators

prisma
generator zod {
  provider                         = "zod-prisma-types"
  output                           = "./generated/zod" // 出力ディレクトリの指定
  useMultipleFiles                 = true // スキーマを複数ファイルに分割
  writeBarrelFiles                 = false // バレルファイルの生成を無効化
  createInputTypes                 = false // 入力タイプの生成を無効化
  createModelTypes                 = true // モデルタイプの生成を有効化
  addInputTypeValidation           = true // 入力タイプに対するバリデーションの追加
  createOptionalDefaultValuesTypes = true // デフォルト値を持つフィールドをオプショナルに
  createRelationValuesTypes        = true // リレーションフィールドを含むタイプの生成
  createPartialTypes               = true // 全フィールドをオプショナルにしたパーシャルタイプの生成
  useDefaultValidators             = false // Zodのデフォルトバリデータの使用を無効化
}

generator markdown {
  provider = "prisma-markdown"
  output   = "./ERD.md"
  title    = "Prisma Markdown"
}

model User {
  id    Int    @id @default(autoincrement())
  email String @unique /// @zod.string.email()
  name  String /// @zod.string.min(1).max(50)
  posts Post[]
}

model Post {
  id       Int    @id @default(autoincrement())
  title    String /// @zod.string.min(1).max(140)
  content  String /// @zod.string.min(1).max(140)
  authorId Int
  author   User   @relation(fields: [authorId], references: [id])
}

Generate

sh
npx prisma generate

Generated Zod

Example

ts
import { z } from 'zod'
import type { UserWithRelations } from './UserSchema'
import type { UserPartialWithRelations } from './UserSchema'
import type { UserOptionalDefaultsWithRelations } from './UserSchema'
import { UserWithRelationsSchema } from './UserSchema'
import { UserPartialWithRelationsSchema } from './UserSchema'
import { UserOptionalDefaultsWithRelationsSchema } from './UserSchema'

/////////////////////////////////////////
// POST SCHEMA
/////////////////////////////////////////

export const PostSchema = z.object({
  id: z.number(),
  title: z.string().min(1).max(140),
  content: z.string().min(1).max(140),
  authorId: z.number(),
})

export type Post = z.infer<typeof PostSchema>

/////////////////////////////////////////
// POST PARTIAL SCHEMA
/////////////////////////////////////////

export const PostPartialSchema = PostSchema.partial()

export type PostPartial = z.infer<typeof PostPartialSchema>

/////////////////////////////////////////
// POST OPTIONAL DEFAULTS SCHEMA
/////////////////////////////////////////

export const PostOptionalDefaultsSchema = PostSchema.merge(
  z.object({
    id: z.number().optional(),
  }),
)

export type PostOptionalDefaults = z.infer<typeof PostOptionalDefaultsSchema>

/////////////////////////////////////////
// POST RELATION SCHEMA
/////////////////////////////////////////

export type PostRelations = {
  author: UserWithRelations
}

export type PostWithRelations = z.infer<typeof PostSchema> & PostRelations

export const PostWithRelationsSchema: z.ZodType<PostWithRelations> = PostSchema.merge(
  z.object({
    author: z.lazy(() => UserWithRelationsSchema),
  }),
)

/////////////////////////////////////////
// POST OPTIONAL DEFAULTS RELATION SCHEMA
/////////////////////////////////////////

export type PostOptionalDefaultsRelations = {
  author: UserOptionalDefaultsWithRelations
}

export type PostOptionalDefaultsWithRelations = z.infer<typeof PostOptionalDefaultsSchema> &
  PostOptionalDefaultsRelations

export const PostOptionalDefaultsWithRelationsSchema: z.ZodType<PostOptionalDefaultsWithRelations> =
  PostOptionalDefaultsSchema.merge(
    z.object({
      author: z.lazy(() => UserOptionalDefaultsWithRelationsSchema),
    }),
  )

/////////////////////////////////////////
// POST PARTIAL RELATION SCHEMA
/////////////////////////////////////////

export type PostPartialRelations = {
  author?: UserPartialWithRelations
}

export type PostPartialWithRelations = z.infer<typeof PostPartialSchema> & PostPartialRelations

export const PostPartialWithRelationsSchema: z.ZodType<PostPartialWithRelations> = PostPartialSchema.merge(
  z.object({
    author: z.lazy(() => UserPartialWithRelationsSchema),
  }),
).partial()

export type PostOptionalDefaultsWithPartialRelations = z.infer<typeof PostOptionalDefaultsSchema> & PostPartialRelations

export const PostOptionalDefaultsWithPartialRelationsSchema: z.ZodType<PostOptionalDefaultsWithPartialRelations> =
  PostOptionalDefaultsSchema.merge(
    z
      .object({
        author: z.lazy(() => UserPartialWithRelationsSchema),
      })
      .partial(),
  )

export type PostWithPartialRelations = z.infer<typeof PostSchema> & PostPartialRelations

export const PostWithPartialRelationsSchema: z.ZodType<PostWithPartialRelations> = PostSchema.merge(
  z
    .object({
      author: z.lazy(() => UserPartialWithRelationsSchema),
    })
    .partial(),
)

export default PostSchema
ts
import { z } from 'zod'
import type { PostWithRelations } from './PostSchema'
import type { PostPartialWithRelations } from './PostSchema'
import type { PostOptionalDefaultsWithRelations } from './PostSchema'
import { PostWithRelationsSchema } from './PostSchema'
import { PostPartialWithRelationsSchema } from './PostSchema'
import { PostOptionalDefaultsWithRelationsSchema } from './PostSchema'

/////////////////////////////////////////
// USER SCHEMA
/////////////////////////////////////////

export const UserSchema = z.object({
  id: z.number(),
  email: z.string().email(),
  name: z.string().min(1).max(50),
})

export type User = z.infer<typeof UserSchema>

/////////////////////////////////////////
// USER PARTIAL SCHEMA
/////////////////////////////////////////

export const UserPartialSchema = UserSchema.partial()

export type UserPartial = z.infer<typeof UserPartialSchema>

/////////////////////////////////////////
// USER OPTIONAL DEFAULTS SCHEMA
/////////////////////////////////////////

export const UserOptionalDefaultsSchema = UserSchema.merge(
  z.object({
    id: z.number().optional(),
  }),
)

export type UserOptionalDefaults = z.infer<typeof UserOptionalDefaultsSchema>

/////////////////////////////////////////
// USER RELATION SCHEMA
/////////////////////////////////////////

export type UserRelations = {
  posts: PostWithRelations[]
}

export type UserWithRelations = z.infer<typeof UserSchema> & UserRelations

export const UserWithRelationsSchema: z.ZodType<UserWithRelations> = UserSchema.merge(
  z.object({
    posts: z.lazy(() => PostWithRelationsSchema).array(),
  }),
)

/////////////////////////////////////////
// USER OPTIONAL DEFAULTS RELATION SCHEMA
/////////////////////////////////////////

export type UserOptionalDefaultsRelations = {
  posts: PostOptionalDefaultsWithRelations[]
}

export type UserOptionalDefaultsWithRelations = z.infer<typeof UserOptionalDefaultsSchema> &
  UserOptionalDefaultsRelations

export const UserOptionalDefaultsWithRelationsSchema: z.ZodType<UserOptionalDefaultsWithRelations> =
  UserOptionalDefaultsSchema.merge(
    z.object({
      posts: z.lazy(() => PostOptionalDefaultsWithRelationsSchema).array(),
    }),
  )

/////////////////////////////////////////
// USER PARTIAL RELATION SCHEMA
/////////////////////////////////////////

export type UserPartialRelations = {
  posts?: PostPartialWithRelations[]
}

export type UserPartialWithRelations = z.infer<typeof UserPartialSchema> & UserPartialRelations

export const UserPartialWithRelationsSchema: z.ZodType<UserPartialWithRelations> = UserPartialSchema.merge(
  z.object({
    posts: z.lazy(() => PostPartialWithRelationsSchema).array(),
  }),
).partial()

export type UserOptionalDefaultsWithPartialRelations = z.infer<typeof UserOptionalDefaultsSchema> & UserPartialRelations

export const UserOptionalDefaultsWithPartialRelationsSchema: z.ZodType<UserOptionalDefaultsWithPartialRelations> =
  UserOptionalDefaultsSchema.merge(
    z
      .object({
        posts: z.lazy(() => PostPartialWithRelationsSchema).array(),
      })
      .partial(),
  )

export type UserWithPartialRelations = z.infer<typeof UserSchema> & UserPartialRelations

export const UserWithPartialRelationsSchema: z.ZodType<UserWithPartialRelations> = UserSchema.merge(
  z
    .object({
      posts: z.lazy(() => PostPartialWithRelationsSchema).array(),
    })
    .partial(),
)

export default UserSchema