Interactions-as-a-Service / d1-orm

A simple, strictly typed ORM, to assist you in using Cloudflare's D1 product
https://docs.interactions.rest/d1-orm/
Apache License 2.0
162 stars 11 forks source link

Infer types does require id to be set despite it being set as Primary Key and AutoIncrement? #65

Open chrisspiegl opened 1 year ago

chrisspiegl commented 1 year ago

I am trying to use d1-orm and the model setup.

I created a model:

new Model(
      {
        D1Orm: orm,
        tableName: 'user_chats',
        primaryKeys: 'id',
        autoIncrement: 'id',
      // uniqueKeys: [['email']],
      },
      {
        id: {
          type: DataTypes.INTEGER,
          notNull: true,
        },
      }
)

My expectation is that then, I can infer the type and it'd know that the id field is kind of optional for inserts and stuff like that?

But doing type UserChats = Infer<typeof models.user_chats>

Followed by a definition if said object:

const userChats: UserChats = {
        }

Shows the type error:

Property 'id' is missing in type '{ }' but required in type 'InferFromColumns<{ id: { type: DataTypes.INTEGER; notNull: true; }; 

I'd hoped that this would just work? Am I missing something? Do I have to update my code somehow to be able to use types with that?

chrisspiegl commented 1 year ago

Adding to this:

in a similar way, even when a value has a defaultValue set, it still forces me to define the property when creating a new object.

Skye-31 commented 1 year ago

The library will make any column that has notNull: true be required. I had played around with ignoring it when a default value is set too, however that wasn't working out. If you're able to improve the experience of Infer, please do open a pull 🙂

For now, if you want to ignore a particular key, I'd use Omit<UserChats, 'id'> to remove it from the type.

chrisspiegl commented 1 year ago

Thanks, for the update. I myself am kind of new to TypeScript and thus a pull request from me is unlikely any time soon from me on this topic.

But a thought would be this:

Isn't it possible to mark types as optional on a type/interface?

export interface Env {
  title?: string
}

Maybe that could be done with the Infer method?

Skye-31 commented 1 year ago

It is possible, and that's what happens when notNull is falsey. It's rather difficult to extend that type to pick up default values, which is the only reason it doesn't currently