K
Kysely•3mo ago
WhyDoThis

Updateable primary key question & .set() type safety

Do you all wrap your Updateable versions of tables to omit id? Or am I doing something unconventional here. Also how do you get typesafety on set() calls to prevent it accepting an item with id (or whatever primary key) from being updated?
Solution:
Hey 👋 To define a column that's never updated, you can use ColumnType with never in the 3rd generic value. ```ts...
Jump to solution
8 Replies
koskimas
koskimas•3mo ago
Updating the id is normal and not something kysely should prevent. It's not a type-safety issue.
Solution
Igal
Igal•3mo ago
Hey 👋 To define a column that's never updated, you can use ColumnType with never in the 3rd generic value.
col: ColumnType<SelectType, InsertType, never>
col: ColumnType<SelectType, InsertType, never>
To define a column that's never inserted nor updated, you can use GeneratedAlways
col: GeneratedAlways<SelectType>
col: GeneratedAlways<SelectType>
To prevent an item from being accepted in .set of an update query, you can use the satisfies keyword with Updateable<MyTable> as follows:
item satisfies Updateable<MyTable>
item satisfies Updateable<MyTable>
This'll compile-time error on any non-updateable columns.
WhyDoThis
WhyDoThisOP•3mo ago
Thanks @Igal I'll check this out! You perfectly understood what I was asking thank you so much. @koskimas I think you misunderstood. I wasn't implying kysely should prevent it out of the box I am asking for those who want to modify so a certain column (like id) can not be passed in say on a patch object unintentionally that's based on the db types generated by kysely which would include it. I appreciate you reading + replying nonetheless.
WhyDoThis
WhyDoThisOP•3mo ago
For future searchers what I doing for now is this:
type WithoutIdCol<T> = Omit<T, "id">; ... export type UserUpdate = Updateable<WithoutIdCol<UserTable>>;
Since its just one more generic wrapper I will leave it but if it grows beyond Id I would just make an Updateable wrapper that does it all. (I've gone this route versus on the column definition because for the table types I am using kysely-codegen and its one less thing to add to my manual modification list I have to do post re-generating) and in set:
... .set({id: 'blah'} satisfies UserUpdate) ...
which now properly TS errors. Thanks again Igal!
TheMelonAssassin
TheMelonAssassin•3mo ago
Is it possible to do the opposite? For instance I want some col to always be present in Insertable or Updatable?
Igal
Igal•3mo ago
Non-nullable columns, T or ColumnType<?, T, ?> are always required in inserts. Updates are always a partial object, by design.
TheMelonAssassin
TheMelonAssassin•3mo ago
Could be me misunderstanding typescript (still getting used to it), but when I hover over my InsertableFoo type it returns the columns with a ?.
WhyDoThis
WhyDoThisOP•3mo ago
@TheMelonAssassin see one of the answers here: https://stackoverflow.com/q/69327990 and what Igal wrote about "satisfies" above.
Stack Overflow
How can I make one property non-optional in a typescript type?
I have this type: type User = { id: string; name?: string; email?: string; } And I would like to construct a similar type with name non optional: type UserWithName = { id: string; name:
Want results from more Discord servers?
Add your server