kysely-org / kysely

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

MySQL Dialect. InsertResult insertId is undefined #316

Closed pergunt closed 1 year ago

pergunt commented 1 year ago

I use MySQL dialect. After I insert a new record and want to get this record by the getter from the InsertResult constructor, I see TypeScript error  **Type 'undefined' is not assignable to type 'OperandValueExpressionOrList<From<DB, "test_users">, "test_users", "id">**

So I have to cast this:


export async function create(name: string) {
  const [result] = await db.insertInto("test_users")
    .values({
      name,
      createdAt: new Date(),
      updatedAt: new Date(),
    })
    .execute()

  return db.selectFrom('test_users')
    .selectAll()
    .where('id', '=', result.insertId  as any) // <---------------- here
    .executeTakeFirst()
}

My question is: "is it a bug that current InsertResult constructor looks like this:


export declare class InsertResult {
    #private;
    constructor(insertId: bigint | undefined, numInsertedOrUpdatedRows: bigint | undefined);
    /**
     * The auto incrementing primary key
     */
    get insertId(): bigint | undefined;
    /**
     * Affected rows count.
     */
    get numInsertedOrUpdatedRows(): bigint | undefined;
}

Why insertID can be undefined if MySQL always returns it after insert operations is done?

igalklebanov commented 1 year ago

Hey 👋

Outside of Kysely class instantiation, the API is dialect agnostic by design.

Reason behind undefined:

You can add a ! assertion as follows:

  return db.selectFrom('test_users')
    .selectAll()
    .where('id', '=', result.insertId!)
    .executeTakeFirst()