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

Unable to assign values to fields marked as Generated in TypeScript. #64

Closed
noccio-nocci opened this issue Aug 4, 2023 · 3 comments
Closed

Comments

@noccio-nocci
Copy link

Fields with @default directives in the Prisma schema are converted to type Generated in the generated type.ts.

While this makes sense for fields where the database is responsible for generating the value (like auto-incremented IDs or timestamps), it becomes problematic for fields where I need to assign a value during insert or update operations. TypeScript throws a type error when I try to assign a value to these Generated fields.

Here's an example of a generated type:

import type { ColumnType } from 'kysely';
export type Generated<T> = T extends ColumnType<infer S, infer I, infer U>
  ? ColumnType<S, I | undefined, U>
  : ColumnType<T, T | undefined, T>;
export type Timestamp = ColumnType<Date, Date | string, Date | string>;

export type User = {
  userId: string;
  userName: string;
  lastName: string | null;
  firstName: string | null;
  email: string;
  emailVerified: Generated<boolean>; // @default(true) in schema.prisma
  phoneNumber: string | null;
  birthdate: string | null;
  enabled: Generated<boolean>;
  createdAt: Generated<Timestamp>;
  updatedAt: Timestamp;
};

Is there a recommended way to handle this situation? Or would you consider adding an option that would allow us to distinguish between fields that are always generated by the database and fields that can be assigned manually?

@valtyr
Copy link
Owner

valtyr commented Aug 21, 2023

Key @noccio-nocci, here's a passage from the Kysely docs:

Columns that are generated by the database should be marked using the Generated type. This way they are automatically made optional in inserts and updates.

Here the key word is optional. Kysely allows the user to optionally provide values for generated fields. There's another type called GeneratedAlways that exhibits the behavior you're describing. To my best knowledge this would be a bug with Kysely itself, if true. It would be cool if you could provide a reproducible example of this error so I can investigate. In the meantime if you're still grappling with this issue you can use per field type overrides.

@mateusm09
Copy link

I did a little type helper that removes the Generated type from the field. So you can use the exported type in other objects.

It scans the provided type looking for the ColumnType (which Generated uses underneath), and infers the first generic type.

import { ColumnType } from 'kysely';
export type Clean<T> = { [K in keyof T]-?: T[K] extends ColumnType<infer S> ? S : T[K] };

type User = {
  id: Generated<string>
  name: string
  age: number
};

type CleanedUser = Clean<User>;

/* result - {
  id: string;
  name: string;
  age: number
} */

@valtyr
Copy link
Owner

valtyr commented May 8, 2024

@mateusm09 The move here would probably be to use the Selectable, Insertable, Updateable etc. type helpers from Kysely. The types generated from prisma-kysely aren't really meant to be used directly in business logic unless you're wrapping the query client itself.

Check out the examples at the bottom of the code block here:
https://kysely.dev/docs/getting-started#types

@valtyr valtyr closed this as completed May 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants