Using this package? Please consider donating to support my open source work ❤️
Help prisma-json-types-generator grow! Star and share this amazing repository with your friends and co-workers!
Generate your prisma client with strict JSON types and String literals!
- Installation
- Quick Start
- Typing
String
Fields (Enums) - Advanced Typing
- Configuration
- Limitations
- How It Works
- License
Supercharge your @prisma/client
by adding strong, custom types to Json
and String
fields. This generator enhances type safety by replacing Prisma's default JsonValue
with your own TypeScript types, ensuring data conforms to your schema before it even reaches the database.
It works with all database drivers supported by Prisma (PostgreSQL, MySQL, SQLite, etc.) without affecting any runtime code.
- Strongly Typed
Json
: Define complex object shapes for yourJson
fields. - String-Based Enums: Type
String
fields to create enums without needing native database enums. - Full Type-Safety: Get autocomplete, intellisense, and compile-time checks for your data structures.
- Zero Runtime Overhead: All transformations happen at generation time.
- Flexible Typing: Define types globally in a namespace or inline directly in your schema.
Install the package as a development dependency in your project.
npm install -D prisma-json-types-generator
Follow these three steps to get started.
-
Add the Generator to Your Schema
In your
schema.prisma
file, add thejson
generator block below the defaultclient
generator.generator client { provider = "prisma-client-js" } generator json { provider = "prisma-json-types-generator" }
-
Define Your Custom Types
Create a type declaration file (e.g.,
src/types.ts
) and ensure it's included in yourtsconfig.json
. Define your types inside thePrismaJson
global namespace.// This file must be a module, so we include an empty export. export {}; declare global { namespace PrismaJson { // Define a type for a user's profile information. type UserProfile = { theme: 'dark' | 'light'; twitterHandle?: string; }; } }
-
Link Types in Your Prisma Schema
Use an AST comment (
/// [TypeName]
) above aJson
field in yourschema.prisma
to link it to your custom type.model User { id Int @id @default(autoincrement()) email String @unique /// [UserProfile] profile Json }
Now, run npx prisma generate
. The profile
field on the User
model will be strongly typed!
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function updateUserProfile() {
const user = await prisma.user.update({
where: { id: 1 },
data: {
profile: {
theme: 'dark'
// twitterHandle is optional
}
}
});
// user.profile is now fully typed as UserProfile!
console.log(user.profile.theme); // 'dark'
}
You can use the same technique to type String
fields, which is perfect for creating "string enums" without using Prisma's native enum
type. This is useful for maintaining a set of allowed values directly in your application code.
Use the inline type syntax (/// ![Type]
) for this.
model Post {
id Int @id @default(autoincrement())
title String
/// !['draft' | 'published' | 'archived']
status String @default("draft")
}
After generating, post.status
will be correctly typed as 'draft' | 'published' | 'archived'
.
The generator offers two ways to define types:
- Namespace-based (
/// [TypeName]
): References a type from thePrismaJson
namespace. Best for complex, reusable types. - Inline (
/// ![Type]
): Defines the type directly in the schema. Best for simple, one-off types like enums or basic objects.
model Product {
id Int @id
// Namespace-based type
/// [ProductMeta]
meta Json?
// Array of namespace-based types
/// [Tag]
tags Json[]
// Inline union type (enum)
/// !['physical' | 'digital']
type String
// Inline object type
/// ![{ width: number; height: number }]
dimensions Json
}
export {};
declare global {
namespace PrismaJson {
type ProductMeta = {
sku: string;
stock: number;
};
type Tag = {
id: string;
name: string;
};
}
}
You can configure the generator in your schema.prisma
file.
generator json {
provider = "prisma-json-types-generator"
namespace = "PrismaJson"
allowAny = false
// etc...
}
Option | Description | Default |
---|---|---|
namespace |
The global namespace where your custom types are defined. | "PrismaJson" |
clientOutput |
Path to the @prisma/client output directory. The generator usually finds this automatically, but you can specify it if needed (e.g., in complex monorepos). |
(auto-detected) |
allowAny |
If true , untyped Json fields will resolve to any . If false , they will resolve to unknown for stricter type safety. |
false |
useType |
Specifies a root type within your namespace to use as a fallback for all untyped Json fields. This adds an index signature [key: string]: any to the specified type. |
undefined |
- Complex Filters: To preserve functionality, types like
JsonFilter
andJsonWithAggregatesFilter
remain untyped. - Prisma Version: This generator supports Prisma v5+ and generator v3+.
- Known Gaps: If you find any
Json
fields that are not being typed correctly, please open an issue.
This tool operates as a standard Prisma generator. When npx prisma generate
runs, the generator receives the Data Model Meta Format (DMMF), which contains your full schema, including the AST comments. After prisma-client-js
finishes, this generator targets its output declaration file (e.g., index.d.ts
) and parses it into an Abstract Syntax Tree (AST) using the TypeScript Compiler API.
It then traverses this AST, and for each property signature in a model, it cross-references the DMMF to find a corresponding type comment. If a match is found, it performs a direct AST transformation, replacing the original type node (like Prisma.JsonValue
or string
) with a new node representing your custom type. Finally, the modified AST is printed back into TypeScript code, overwriting the original declaration file. This entire process occurs at build time and adds no runtime overhead. For a deeper dive, see the core implementation.
Licensed under the MIT. See LICENSE
for more informations.