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
null
values 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
null
s in JSON fields, they are prohibited due to being ambiguous. Instead, you have to explicitly specifyPrisma.DbNull
orPrisma.JsonNull
to 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
null
values”, while this also applies tocreate
,insert
andupsert
— 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
null
for both JSONnull
and DBNULL
, while our insert operations are more strict. However, returningPrisma.DbNull
andPrisma.JsonNull
in 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 ifjsonField
isnull
. Ifnull
is accepted by runtime validation — please let us know, that would be a bug!Finally, none of this is relevant to MongoDB, and
null
must 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.ts
Just want to confirm this bug still exists in
3.7.0
and 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.