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!
String
Fields (Enums)
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.
Json
: Define complex object shapes for your Json
fields.String
fields to create enums without needing native database enums.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 the json
generator block below the default client
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 your tsconfig.json
. Define your types inside the PrismaJson
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 a Json
field in your schema.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'
}
String
Fields (Enums)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:
/// [TypeName]
): References a type from the PrismaJson
namespace. Best for complex, reusable types./// ![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 |
JsonFilter
and JsonWithAggregatesFilter
remain untyped.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.