JSON type throws error on certain types of valid JSON on create
and update
#716
Comments
Thanks for raising the issue @thesunny ! If we add Is there anything from your side that speaks against using |
Hi @timsuchanek, I think it's prudent to apply the Principle of Least Surprise https://en.wikipedia.org/wiki/Principle_of_least_astonishment One of the criticisms of old MySQL was that it would silently type cast things that in other databases would raise errors. In the same way, it feels surprising to me to pass in a For me, the principle of least surprise for an ORM is that if I put a certain type of data in, it comes back as the same type.
Due to a limitation in TypeScript, we can't actually describe optional values without also adding Also, for clarity, for data coming out of Prisma (ie. By the way, I've made workaround to all these issues for myself so they are no longer critical for me; however, Prisma is so great, that I really want it to gain greater adoption. I think paying attention to these little details will pay off, kind of in the same way that you've paid attention to getting the typing right with partial selects and your really interesting and smart choices around how foreign keys affect the call signatures. Prisma has literally caused me to create better models because of how the better models create better UI. |
Thanks for the elaborate answer and the kind words. We'll call your |
Thanks a lot for reporting 🙏 In case it’s not fixed for you - please let us know and we’ll reopen this issue! |
Hi @timsuchanek Thanks for the update. Really appreciate the work you and everyone on your team put into Prisma. |
Thank you @Jolg42 for addressing the previous two JSON issues:
string
. prisma#2619 (comment)This issue is the last (I think) for end-to-end JSON typing to work.
Bug description
We get a TypeScript error during a
create
orupdate
for valid JSON in a JSON column if it contains optional properties like this.The reason this happens is because TypeScript transforms the value of the
age
property by addingundefined
so that it becomesnumber | undefined
. The preceding type and the following type are identical:This is a known limitation of TypeScript. It cannot distinguish a missing property from a property which can be set to
undefined
. microsoft/TypeScript#13195How to reproduce
create
orupdate
to the JSON column with a valid JSON object that has an optional propertyThis code clarifies why this happens:
Expected behavior
The way to fix it is to define a
UJsonValue
like this and use that to type JSON values in acreate
orupdate
:The most accurate and strictest way to type this is to have the
find
methods return aJsonValue
and thecreate
andupdate
methods to accept aUJsonValue
.This works because JSON data coming out of Prisma is guaranteed to be in the restrictive
JsonValue
type. It never containsundefined
.In an end to end API, that value comes out of the database will then be typed into something like
User
.The end user makes a change and saves it to Prisma. The JSON data coming into Prisma should accept
UJsonValue
. If it is typed to acceptJsonValue
, we get a TypeScript error even thoughUser
is valid JSON.The less accurate method is to add
undefined
toJsonValue
and be done with it; however, this affects users that are strictly typing their API against JsonValue as typed intype-fest
. It won't affect me and I think most users because if it flows through an API, that API has to acceptundefined
or else it breaks whenever there is an optional property (ie. same problem in a different place).In order of desirability, it goes like this:
JsonValue
forfind
andUJsonValue
forcreate
andupdate
(Fixes all cases)JsonValue
extended withundefined
(solves all my use cases and probably most people)JsonValue
as it is (breaks valid JSON with optional properties oncreate
andupdate
)## Prisma information
Beta 2.0.0-beta7
Environment & setup
The text was updated successfully, but these errors were encountered: