mswjs / data

Data modeling and relation library for testing JavaScript applications.
https://npm.im/@mswjs/data
MIT License
772 stars 51 forks source link

Help Creating Type-Safe Models #282

Open kjrocker opened 11 months ago

kjrocker commented 11 months ago

I'm working on an application where all the BE types are compiled into Typescript for me. I would love to be able to enforce type-safety on the models in factory to some extent.

I've got the following code

type User = {
  id: string;
  firstName: string;
  lastName: string;
};

export const db = factory({
  user: {
    id: primaryKey(() => 'abc-123'),
    firstName: () => 'John',
    lastName: () => 'Maverick',
  }
})

Obviously because of the getters I can't just do user: { .... } as User

I also tried defining type Factory<T> = { [P in keyof T]-?: () => T[P] };

With that, I can do user: { .... } as Factory<User>, which works for simple fields, but breaks for anything using primaryKey, manyOf, oneOf, etc.

Any thoughts? I'd really just like to make sure I'm not missing keys when I define new models.

kettanaito commented 11 months ago

Hi, @kjrocker. This is a valid concern. I'm working on the updated version of this library that covers improves type-safety as well. I can't promise to implement this into the existing version due to the lack of availability. But I do hope to get the new version out sometime soon (~this year).

In the next version, I tended to give the Schema generic to the consumer to specify the model on the type level:

type Models = {
  user: {
    id: Number
  }
  book: {
    id: number
    author: Relationship<'oneOf', 'user'>
  }
}

const db = factory<Models>({
  user: {
    id: id(Number)
  },
  book: {
    id: id(Number),
    author: oneOf('user')
  }
})

This is a bit tricky but I think I'm slowly getting it right internally. If you have some use cases to share please do, they can help a lot!

pfe-nazaries commented 1 month ago

Same problem here