prisma: Incorrect InputJsonValue type
Bug description
Hello!
Right now JsonValue is not assignable to InputJsonValue and I think it is incorrect because I believe InputJsonValue is supposed to be a wider type.
Probably
export type InputJsonValue = string | number | boolean | InputJsonObject | InputJsonArray
// should be
export type InputJsonValue = string | number | boolean | InputJsonObject | InputJsonArray | null
How to reproduce
Get any model that has a JSON field and try to use this field in for example in update and see
Type 'JsonValue' is not assignable to type 'InputJsonValue'.
Type 'null' is not assignable to type 'InputJsonValue'.
Expected behavior
JsonValue being assignable to InputJsonValue
Prisma information
model AnyModel {
...
jsonField Json
...
}
const rec = prisma.anyModel.findUnique({});
prisma.anyModel.update({ data: { jsonField: rec.jsonField } });
Environment & setup
Typescritp: 4.4.3 { "strict": true }
Prisma Version
prisma : 3.0.2
@prisma/client : 3.0.2
Current platform : debian-openssl-1.1.x
Query Engine (Node-API) : libquery-engine 2452cc6313d52b8b9a96999ac0e974d0aedf88db (at ../../node_modules/@prisma/engines/libquery_engine-debian-openssl-1.1.x.so.node)
Migration Engine : migration-engine-cli 2452cc6313d52b8b9a96999ac0e974d0aedf88db (at ../../node_modules/@prisma/engines/migration-engine-debian-openssl-1.1.x)
Introspection Engine : introspection-core 2452cc6313d52b8b9a96999ac0e974d0aedf88db (at ../../node_modules/@prisma/engines/introspection-engine-debian-openssl-1.1.x)
Format Binary : prisma-fmt 2452cc6313d52b8b9a96999ac0e974d0aedf88db (at ../../node_modules/@prisma/engines/prisma-fmt-debian-openssl-1.1.x)
Default Engines Hash : 2452cc6313d52b8b9a96999ac0e974d0aedf88db
Studio : 0.423.0
Preview Features : orderByRelation
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 35
- Comments: 15 (5 by maintainers)
This behaviour makes duplicating documents in mongo very cumbersome. I want to do this:
But because of this difference in types I have to manually go through all the json fields. May be I should do this differently?
This is not a bug, we explicitly designed the API this way — but it’s now clear that it might not be optimal or convenient in all cases.
What would have been a bug, though, is if nested
nullvalues inside a JSON value were prohibited:However, this is not the case — the snippet above works fine and doesn’t produce any errors.
As for the top-level
nulls in JSON fields, they are prohibited due to being ambiguous. Instead, you have to explicitly specifyPrisma.DbNullorPrisma.JsonNullto choose the kind of “null” you want, so Prisma knows what you mean.We should make the documentation about it more discoverable, because the title of the section refers to “Filtering by
nullvalues”, while this also applies tocreate,insertandupsert— which is also explicitly stated in the documentation, but I understand it might be hard to find it.Now, as for it not being possible to re-use the value that you got from the database — I agree that it is not very ergonomic. The problem here is that we lose information when retrieving the value from the DB: Prisma returns JavaScript
nullfor both JSONnulland DBNULL, while our insert operations are more strict. However, returningPrisma.DbNullandPrisma.JsonNullin results would come with even more ergonomics and DX implications. What we should do here and how we should change it in the future major versions is a subject for discussion, but for now it’s what the API contract is.The correct way to do this is like this:
Do not override the type system and cast it (i.e.,
jsonField: record.jsonField as Prisma.JsonObject) like some of the workarounds above suggest. The types are correct and represent the actual expectations — what those workarounds suggest will fail at run time ifjsonFieldisnull. Ifnullis accepted by runtime validation — please let us know, that would be a bug!Finally, none of this is relevant to MongoDB, and
nullmust be accepted at the top level there. Please open an issue if that’s not the case for you, and you encounter this issue with MongoDB.I’ll update the issue description and change the labels accordingly.
work around using spread:
This is quite annoying… if I don’t do this I get ->
Full code for context:
and then in
user.model.tsJust want to confirm this bug still exists in
3.7.0and I just stumbled upon it today.Thanks for the issue. For now, the workaround is:
I think InputJsonObject should allow nulls as its field values even if InputJsonValue does not allow null.
Did not work for me, instead, I’m typing the value as a
Prisma.JsonObject:Not sure if it works with every use case, though…
Any updates on that? I’m wondering how this issue is not prioritized and have more traction here, because we just updated from 2.3.0 to 3.7.0 and all our code is full with this problem (yes, we have many Json columns 😦 ).
It seems like this is actually intentional, but then it’s hard to update a single field of a JsonObject and write the result back into the database — any field might be “null” and the workaround above doesn’t work.