Skip to content

fix(typescript): overload batch for either array or spread args#1964

Open
grddavies wants to merge 1 commit into
Nozbe:masterfrom
grddavies:fix/batch-ts-type
Open

fix(typescript): overload batch for either array or spread args#1964
grddavies wants to merge 1 commit into
Nozbe:masterfrom
grddavies:fix/batch-ts-type

Conversation

@grddavies
Copy link
Copy Markdown

The typescript types for Database.batch allows spreading an array that includes an array of operations, despite the fact that this causes a runtime error:

This snippet shows how this can result in runtime errors:

import { Database, Model, appSchema, tableSchema } from '@nozbe/watermelondb'
import SQLiteAdapter from '@nozbe/watermelondb/adapters/sqlite'
import { text } from '@nozbe/watermelondb/decorators'

type Operation = Model | Model[]

export const schema = appSchema({
  version: 1,
  tables: [
    tableSchema({
      name: 'foo',
      columns: [{ name: 'bar', type: 'string' }],
    }),
  ],
})

class FooModel extends Model {
  static table = 'foo'
  @text('bar') bar!: string
}

const database = new Database({
  adapter: new SQLiteAdapter({ dbName: ':memory:', schema }),
  modelClasses: [FooModel],
})

export class Transaction {
  private readonly ops: Operation[] = []

  register(...operations: Operation[]): void {
    this.ops.push(...operations)
  }

  async commit(database: Database): Promise<void> {
    const ops = this.ops.splice(0)
    await database.write(() => database.batch(...ops))
  }
}

const tx = new Transaction()

let i = 0
const createModel = () =>
  database
    .get<FooModel>('foo')
    .prepareCreate((record) => (record.bar = `${i++}`))

async function main() {
  // works
  tx.register(createModel())
  await tx.commit(database)
  console.log('ok')

  // works
  tx.register([createModel(), createModel()])
  await tx.commit(database)
  console.log('ok')

  // TypeError: Cannot read properties of undefined (reading '_status')
  tx.register(createModel(), [createModel(), createModel()])
  await tx.commit(database)
  console.log('ok?')
}

main()

After updating the type definitions we get a compiler error in Transaction.commit:

Type 'Model[]' is not assignable to type 'false | void | Model | null'. ts (2345)

May be related to #1952

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

Successfully merging this pull request may close these issues.

1 participant