W
Wasp3w ago
Noah

Supporting decimals in prisma schema

My schema has fields like so:
model PaymentRule {
id String @id @default(uuid())
venueId String
venue Venue @relation(fields: [venueId],
pricePerHour Decimal
}
model PaymentRule {
id String @id @default(uuid())
venueId String
venue Venue @relation(fields: [venueId],
pricePerHour Decimal
}
Then when I write an operation to fetch Payment rules, I get the following error:
export const getVenueById: GetVenueById<
GetVenueByIdPayload,
(Venue & { spaces: Space[]; availabilityRules: AvailabilityRule[]; paymentRules: PaymentRule[] }) | null
> = async (args, context) => {
return context.entities.Venue.findFirst({
where: { id: args.venueId },
include: {
spaces: true,
availabilityRules: true,
paymentRules: true,
},
});
};
export const getVenueById: GetVenueById<
GetVenueByIdPayload,
(Venue & { spaces: Space[]; availabilityRules: AvailabilityRule[]; paymentRules: PaymentRule[] }) | null
> = async (args, context) => {
return context.entities.Venue.findFirst({
where: { id: args.venueId },
include: {
spaces: true,
availabilityRules: true,
paymentRules: true,
},
});
};
Property 'paymentRules' is incompatible with index signature.
Type '{ id: string; venueId: string; spaceIds: string[]; priority: number; ruleType: RuleType; pricePerHour: Decimal | null; multiplier: Decimal | null; discountRate: Decimal | null; ... 8 more ...; updatedAt: Date; }[]' is not assignable to type 'SuperJSONValue'.
...
Property 'pricePerHour' is incompatible with index signature.
Type 'Decimal | null' is not assignable to type 'SuperJSONValue'.
Type 'Decimal' is not assignable to type 'SuperJSONValue'.
Type 'Decimal' is not assignable to type 'SuperJSONObject'.
Index signature for type 'string' is missing in type 'Decimal'.ts(2344)
Property 'paymentRules' is incompatible with index signature.
Type '{ id: string; venueId: string; spaceIds: string[]; priority: number; ruleType: RuleType; pricePerHour: Decimal | null; multiplier: Decimal | null; discountRate: Decimal | null; ... 8 more ...; updatedAt: Date; }[]' is not assignable to type 'SuperJSONValue'.
...
Property 'pricePerHour' is incompatible with index signature.
Type 'Decimal | null' is not assignable to type 'SuperJSONValue'.
Type 'Decimal' is not assignable to type 'SuperJSONValue'.
Type 'Decimal' is not assignable to type 'SuperJSONObject'.
Index signature for type 'string' is missing in type 'Decimal'.ts(2344)
How to resolve??
4 Replies
kapa.ai
kapa.ai3w ago
Hi @Noah. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- The issue you're encountering is related to how Wasp handles Prisma's Decimal type when serializing data. The Decimal type is not directly serializable to JSON, which is causing the type incompatibility error you're seeing. To resolve this issue, you have a couple of options: 1. Convert Decimal to string or number: You can modify your query to convert the Decimal fields to strings or numbers before returning them. This approach ensures that the data is serializable.
export const getVenueById: GetVenueById<
GetVenueByIdPayload,
(Venue & { spaces: Space[]; availabilityRules: AvailabilityRule[]; paymentRules: PaymentRule[] }) | null
> = async (args, context) => {
const venue = await context.entities.Venue.findFirst({
where: { id: args.venueId },
include: {
spaces: true,
availabilityRules: true,
paymentRules: true,
},
});

if (venue) {
venue.paymentRules = venue.paymentRules.map(rule => ({
...rule,
pricePerHour: rule.pricePerHour ? rule.pricePerHour.toString() : null,
multiplier: rule.multiplier ? rule.multiplier.toString() : null,
discountRate: rule.discountRate ? rule.discountRate.toString() : null,
}));
}

return venue;
};

export const getVenueById: GetVenueById<
GetVenueByIdPayload,
(Venue & { spaces: Space[]; availabilityRules: AvailabilityRule[]; paymentRules: PaymentRule[] }) | null
> = async (args, context) => {
const venue = await context.entities.Venue.findFirst({
where: { id: args.venueId },
include: {
spaces: true,
availabilityRules: true,
paymentRules: true,
},
});

if (venue) {
venue.paymentRules = venue.paymentRules.map(rule => ({
...rule,
pricePerHour: rule.pricePerHour ? rule.pricePerHour.toString() : null,
multiplier: rule.multiplier ? rule.multiplier.toString() : null,
discountRate: rule.discountRate ? rule.discountRate.toString() : null,
}));
}

return venue;
};

2. Use Prisma's toJSON method: Prisma provides a toJSON method that can be used to convert the entire result to a JSON-serializable format. This method automatically handles Decimal fields.
export const getVenueById: GetVenueById<
GetVenueByIdPayload,
(Venue & { spaces: Space[]; availabilityRules: AvailabilityRule[]; paymentRules: PaymentRule[] }) | null
> = async (args, context) => {
const venue = await context.entities.Venue.findFirst({
where: { id: args.venueId },
include: {
spaces: true,
availabilityRules: true,
paymentRules: true,
},
});

return venue ? JSON.parse(JSON.stringify(venue)) : null;
};

export const getVenueById: GetVenueById<
GetVenueByIdPayload,
(Venue & { spaces: Space[]; availabilityRules: AvailabilityRule[]; paymentRules: PaymentRule[] }) | null
> = async (args, context) => {
const venue = await context.entities.Venue.findFirst({
where: { id: args.venueId },
include: {
spaces: true,
availabilityRules: true,
paymentRules: true,
},
});

return venue ? JSON.parse(JSON.stringify(venue)) : null;
};

Both of these approaches should resolve the type incompatibility error you're experiencing. The first option gives you more control over how the Decimal fields are converted, while the second option is more straightforward but converts all fields to JSON-serializable formats. It's worth noting that this issue arises because Wasp uses SuperJSON for serialization, which doesn't natively support Prisma's Decimal type. The solutions provided above work around this limitation by converting the data to a format that SuperJSON can handle. For more information on Prisma configuration in Wasp, you can refer to the Wasp documentation on Prisma Configuration. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @Noah, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
Vinny (@Wasp)
Vinny (@Wasp)3w ago
Did that work @Noah ?
miho
miho3w ago
This might be related to how we handle operation results serialisation - we might not support Decimal as a Prisma type. We should probably implement a custom serializer for the Prisma.Decimal type: https://github.com/flightcontrolhq/superjson?tab=readme-ov-file#decimaljs--prismadecimal @Noah in the meantime, I'd recommend transforming that field into a string on the server and then sending it to the client
GitHub
GitHub - flightcontrolhq/superjson: Safely serialize JavaScript exp...
Safely serialize JavaScript expressions to a superset of JSON, which includes Dates, BigInts, and more. - flightcontrolhq/superjson
Noah
NoahOP3w ago
Yeah I just did the string conversion and it worked fine, thanks! I did like type TypesafeResult = Omit<TypeUnsafeType, 'decimalField'> & { decimalField: string} in the operation

Did you find this page helpful?