kysely-org / kysely

A type-safe typescript SQL query builder
https://kysely.dev
MIT License
10.82k stars 275 forks source link

Generated Timestmap column type - struggling to actually set a value #1206

Closed drew-dulgar closed 2 weeks ago

drew-dulgar commented 3 weeks ago

Hello - I have a timestamp column in postgres, and I am just having the hardest of time trying to understand why i can't actually use the Generated type definition with this while assigning a value. I do admit i am a bit of a typescript noob, so i hope i'm just missing something silly.

In the given scenario, I only need to update this specific date column (as a patch), so it's a pretty paired down version of Updateable.

Migration

  await db.schema
    .createTable('accounts').ifNotExists()
    .addColumn('id', 'integer', col => col.primaryKey().generatedByDefaultAsIdentity())
    .addColumn('login_last', 'timestamp')
    .execute();

Type Definitions

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>;

Account Table Types

export interface AccountTable {
  id: Generated<number>;
  login_last: Generated<Timestamp> | null;
};

export type AccountSelectable = Selectable<AccountTable>;
export type AccountInsertable = Insertable<AccountTable>;
export type AccountUpdateable = Updateable<AccountTable>;

Usage

const updateLastLogin = async ({
  id,
  login_last
}: Pick<AccountUpdateable, 'id' | 'login_last'>): Promise<void> => {

  const query = await db
    .updateTable('accounts')
    .set({ login_last})
    .where('id', '=', id)
    .executeTakeFirstOrThrow();
}

Call the query

updateLastLogin({
  id: 5,
  login_last: new Date()
});

I am now getting a Type 'Date' is missing the following properties from type 'Timestamp': __select__, __insert__, __update__ts(2739)

Screenshot from 2024-11-01 18-08-01

Or if trying with a string...

Call the query

updateLastLogin({
  id: 5,
  login_last: new Date().toISOString()
});

Type 'string' is not assignable to type 'Timestamp'. Screenshot from 2024-11-01 18-10-15

Any thoughts here? I just really want to update a column in a database table with the current time stamp, but i am stumped here.

koskimas commented 2 weeks ago

Just get rid of that weird extra Generated type and use the internal types. Also move | null inside the Column type helper instead of outside.

drew-dulgar commented 2 weeks ago

The weird Generated type came from kysely-codegen. Shall I raise the issue over there?

koskimas commented 2 weeks ago

Your example seems to works perfectly 🤔

https://kyse.link/ICg6p

You probably used Pick<AccountTable 'id' | 'login_last'> at some point and got the error then?