Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript compilation fails when calling create() with model having Json field #10741

Open
teemupiiroinenwirepas opened this issue Dec 17, 2021 · 9 comments
Labels
bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. domain/client Issue in the "Client" domain: Prisma Client, Prisma Studio etc. kind/bug A reported bug. tech/typescript Issue for tech TypeScript. topic: create() topic: Json Scalar type `Json`

Comments

@teemupiiroinenwirepas
Copy link

teemupiiroinenwirepas commented Dec 17, 2021

Bug description

We have been using Prisma now for few weeks, and noticed that for some reason we are not able to call create/createMany with Prisma model instance with Json field, as TypeScript compilation fails.

How to reproduce

index.ts

'use strict'

import PrismaPkg, { Prisma, MyModel } from '@prisma/client';
const { PrismaClient } = PrismaPkg;
const prismaInstance = new PrismaClient();

let myJsonInstance = [
  { name: 'Bob the dog' },
  { name: 'Claudine the cat' },
] as Prisma.JsonArray

const myModelInstance: MyModel = {
  id: 1,
  my_json_field: myJsonInstance
}

prismaInstance.myModel.create({ data: myModelInstance });

Compilation error from tsc

src/index.ts:17:33 - error TS2322: Type 'MyModel' is not assignable to type '(Without<MyModelCreateInput, MyModelUncheckedCreateInput> & MyModelUncheckedCreateInput) | (Without<...> & MyModelCreateInput)'.
  Type 'MyModel' is not assignable to type 'Without<MyModelUncheckedCreateInput, MyModelCreateInput> & MyModelCreateInput'.
    Type 'MyModel' is not assignable to type 'MyModelCreateInput'.
      Types of property 'my_json_field' are incompatible.
        Type 'JsonValue' is not assignable to type 'string | number | boolean | InputJsonObject | InputJsonArray | undefined'.
          Type 'null' is not assignable to type 'string | number | boolean | InputJsonObject | InputJsonArray | undefined'.

17 prismaInstance.myModel.create({ data: myModelInstance });
                                   ~~~~

  node_modules/.prisma/client/index.d.ts:1442:5
    1442     data: XOR<MyModelCreateInput, MyModelUncheckedCreateInput>
             ~~~~
    The expected type comes from property 'data' which is declared here on type '{ select?: MyModelSelect | null | undefined; data: (Without<MyModelCreateInput, MyModelUncheckedCreateInput> & MyModelUncheckedCreateInput) | (Without<...> & MyModelCreateInput); }'


Found 1 error.

Expected behavior

No response

Prisma information

schema.prisma

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model MyModel {
  id                Int     @id
  my_json_field     Json?
}

Environment & setup

  • OS: Windows/WSL1
  • Database: PostgreSQL
  • Node.js version: v17.1.0

Prisma Version

prisma                  : 3.6.0
@prisma/client          : 3.6.0
Current platform        : debian-openssl-1.1.x
Query Engine (Node-API) : libquery-engine dc520b92b1ebb2d28dc3161f9f82e875bd35d727 (at ../../../../../home/xxx/.nvm/versions/node/v17.1.0/lib/node_modules/prisma/node_modules/@prisma/engines/libquery_engine-debian-openssl-1.1.x.so.node)
Migration Engine        : migration-engine-cli dc520b92b1ebb2d28dc3161f9f82e875bd35d727 (at ../../../../../home/xxx/nvm/versions/node/v17.1.0/lib/node_modules/prisma/node_modules/@prisma/engines/migration-engine-debian-openssl-1.1.x)
Introspection Engine    : introspection-core dc520b92b1ebb2d28dc3161f9f82e875bd35d727 (at ../../../../../home/xxx/.nvm/versions/node/v17.1.0/lib/node_modules/prisma/node_modules/@prisma/engines/introspection-engine-debian-openssl-1.1.x)
Format Binary           : prisma-fmt dc520b92b1ebb2d28dc3161f9f82e875bd35d727 (at ../../../../../home/xxx/.nvm/versions/node/v17.1.0/lib/node_modules/prisma/node_modules/@prisma/engines/prisma-fmt-debian-openssl-1.1.x)
Default Engines Hash    : dc520b92b1ebb2d28dc3161f9f82e875bd35d727
Studio                  : 0.440.0
@teemupiiroinenwirepas teemupiiroinenwirepas added the kind/bug A reported bug. label Dec 17, 2021
@janpio janpio added domain/client Issue in the "Client" domain: Prisma Client, Prisma Studio etc. topic: Json Scalar type `Json` bug/0-unknown Bug is new, does not have information for reproduction or reproduction could not be confirmed. labels Dec 17, 2021
@leppaott
Copy link

leppaott commented Feb 11, 2022

@janpio Basically the issue is here: https://www.prisma.io/docs/concepts/components/prisma-client/crud#create-a-single-record-using-generated-types Why the user on that example is created with type Prisma.UserCreateInput okay. But if you already have a user of type Prisma.User shouldn't this work just fine at least in most examples. Basically we now have an issue where we have users of type Prisma.User but they can't be used to call like createMany without (user as Prisma.CreateManyInput) or (user as DeleteManyInput) also DeleteManyInput works just fine for createMany but simple ** Model User ** type doesn't work although has the same keys...

Seems Prisma.JsonValue | null of "Model User" and CreateManyInput of NullableJsonNullValueInput | InputJsonValue are conflicting...
Types of property 'fieldname' are incompatible. Type 'JsonValue' is not assignable to type 'string | number | boolean | InputJsonObject | InputJsonArray | undefined'. Type 'null' is not assignable to type 'string | number | boolean | InputJsonObject | InputJsonArray | undefined'.

Yeah just that in our model it can be "null" or "missing" but of course for input can't be null or need to be set to Prisma.DbNull etc... Trying to come up with a solution.

Required only a little trickery to force NonNullable field.

@binajmen
Copy link

I have the same issue on my project. Did you find out a solution/workaround besides typing as any? 😞

@teemupiiroinenwirepas
Copy link
Author

I have the same issue on my project. Did you find out a solution/workaround besides typing as any? 😞

You can make your own type from the Prisma generated type where you override the JSON field to be "NonNullable"

type PrismaMyTypeNonNull = PrismaMyType & { myJSONField: NonNullable<PrismaMyType['myJSONField']>; };

@binajmen
Copy link

Excuse my ignorance, but what if the Json can be null, that is defines as Json? in the prisma schema.

Isn't the override "unsyncing" the reality?

@teemupiiroinenwirepas
Copy link
Author

Excuse my ignorance, but what if the Json can be null, that is defines as Json? in the prisma schema.

Isn't the override "unsyncing" the reality?

It depends what you do in TS side. It works in our case.

@janpio janpio added the tech/typescript Issue for tech TypeScript. label Mar 24, 2022
@pantharshit00 pantharshit00 added bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. and removed bug/0-unknown Bug is new, does not have information for reproduction or reproduction could not be confirmed. labels Jun 2, 2022
@stephyswe
Copy link

how to add the type?

@imendi
Copy link

imendi commented Oct 19, 2022

Any chance this gets fixed any time soon ? 🙏 In my case I experience it with nullable Json fields as well.

error TS2322: Type '{ my_field: JsonValue; }' is not assignable to type '(Without<mymodelCreateInput, mymodelUncheckedCreateInput> & mymodelUncheckedCreateInput) | (Without<...> & mymodelCreateInput)'.
  Type '{ my_field: JsonValue; }' is not assignable to type 'Without<mymodelUncheckedCreateInput, mymodelCreateInput> & momodelCreateInput'.
    Type '{ my_field: JsonValue; }' is not assignable to type 'momodelCreateInput'.
      Types of property 'my_field' are incompatible.
        Type 'JsonValue' is not assignable to type 'NullableJsonNullValueInput | InputJsonValue | undefined'.
          Type 'null' is not assignable to type 'NullableJsonNullValueInput | InputJsonValue | undefined'.

@leppaott
Copy link

leppaott commented Mar 10, 2023

The model field is of type:
export type JsonValue = string | number | boolean | JsonObject | JsonArray | null
Related https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#using-null-values

/**

  • Matches any valid value that can be used as an input for operations like
  • create and update as the value of a JSON field. Unlike JsonValue, this
  • type allows read-only arrays and read-only object properties and disallows
  • null at the top level.
  • null cannot be used as the value of a JSON field because its meaning
  • would be ambiguous. Use Prisma.JsonNull to store the JSON null value or
  • Prisma.DbNull to clear the JSON value and set the field to the database
  • NULL value instead.
  • @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-by-null-values
    */
    export type InputJsonValue = string | number | boolean | InputJsonObject | InputJsonArray

Seems this is due to JSON null being ambiguous and there being 3 enums for NULL....

Null in the context of create/update should be indeed Prisma.DbNull,to make updates/creates and typescript to work with a model where the JSON field is optional. If you really wanted a "null" to go in the JSON then that should be opt-in behavior by Prisma.JsonNull,. If the JSON field is required, then the default could JsonNull. I understand a bit more why it's not like as it could be a bit confusing.

Suggestion:

JsonField Optional = Use Prisma.DbNull as we don't want to set the JSON field then,
if we really needed "null" use Prisma.JsonNull but most likely we really just need the value or "undefined"

JsonField Required = Use Prisma.JsonNull if we set the field to null we really want to store "null"
as null is a value it's okay - there is no undefined 

@janpio janpio changed the title TypeScript compilation fails when calling create with model having Json field TypeScript compilation fails when calling create with model having Json field Jun 12, 2023
@stephenasuncionDEV
Copy link

stephenasuncionDEV commented Aug 19, 2023

Same with if using Json[] on schema, I'm getting Type 'JsonArray' is not assignable to type 'WidgetCreatefallbackDataInput | InputJsonValue[] | undefined'.

Edit:
Apparently, you're not supposed to use Json[] on Prisma schema if dealing with arrays, Json will work just fine.

@janpio janpio changed the title TypeScript compilation fails when calling create with model having Json field TypeScript compilation fails when calling create() with model having Json field Aug 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. domain/client Issue in the "Client" domain: Prisma Client, Prisma Studio etc. kind/bug A reported bug. tech/typescript Issue for tech TypeScript. topic: create() topic: Json Scalar type `Json`
Projects
None yet
Development

No branches or pull requests

8 participants