The error happens because Prisma's Json type is a union of all valid JSON types: string | number | boolean | null | JsonObject | JsonArray.
TypeScript is complaining because a string or a number does not have a property named low_number . Even though you know user.data is likely an object, TypeScript must account for the possibility that it might be a primitive value.
Here are the three best ways to fix this:
1. The Cleanest Way (Type Assertion)
If you are confident that data is an object (or null), you can cast it to a custom interface or any. This is the most common approach for Prisma JSON fields.
typescript
// Define what your JSON looks like
interface UserData {
low_number?: number;
}
const low_number = (user.data as UserData)?.low_number ?? -1;
2. Using Prisma's JsonObject type
If you don't want to create a custom interface, you can cast it to Prisma's built-in JsonObject type. You must import it from @prisma/client.
typescript
import { Prisma } from '@prisma/client';
// ...
const data = user.data as Prisma.JsonObject;
const low_number = data?.low_number ?? -1;
3. The "Quick and Dirty" Way
If you don't care about strict typing for this specific variable, cast it to any.
typescript
const low_number = (user.data as any)?.low_number ?? -1;
4. The Safest Way (Type Guard)
If you want to be 100% safe at runtime to ensure the code doesn't crash if the JSON is malformed (e.g., it's actually a string), check the type:
typescript
let low_number = -1;
if (user.data && typeof user.data === 'object' && !Array.isArray(user.data)) {
const data = user.data as Record<string, any>;
low_number = data.low_number ?? -1;
}
Why your original code failed:
typescript
// This fails because even if user.data is truthy,
// it might be the string "hello", and "hello".low_number is invalid.
user.data && user.data.low_number
Recommendation: Use Option 1 . Defining an interface makes your code much more maintainable as your data field grows with more properties.