DEV Community

Discussion on: Handling nested data in Vue with Vuex ORM

Collapse
 
vilimco profile image
Vilim Stubičan

Model interfaces
When you define a model and want to use the properties you set it, Typescript will argue that the properties you are using do not exist. I'm assuming this has to do with the facts they are nested in the "fields" property. >Not a major issue, but you would have to write an additional interface to escape the errors.

You can tackle this with interfaces as you suggested, but from my experience, defining an interface for every single model will eventually become awfully troublesome. :/

I found a couple of different approaches to this problem, but the only one that actually will work every time is declaring dynamic attributes on your classes with [key: string]: any.

Let's take your example:

export default class OfferItem extends Model {
   /*....*/
}
Enter fullscreen mode Exit fullscreen mode

You could either add this definition to that class or, to avoid defining this in every Model extension, extend your own Model and define it there.

export default class OfferItem extends Model {
   [key: string]: any; // say that in OfferItem we have some attributes and use them as any
   /*....*/
}


/* other example */
export default class CustomisedModel extends Model { // possibly needs to be abstract?
   [key: string]: any; // say that in CustomisedModel we have some attributes and use them as any
}

export default class OfferItem extends CustomisedModel {
   /*....*/
}
Enter fullscreen mode Exit fullscreen mode

In the second example, you get all benefits of the ORM model, but you also get rid of the all property warnings that the transpiler founds.

There is also an approach with definite assignment assertions (typescriptlang.org/docs/handbook/r...). With them, you can say to the transpiler "Ok, I know that I have this, but you just can't find it due to some magic happening here, but don't worry, I know that I have this.".

With this, you will have to define every single field in entities beside listing them in the static fields().

export default class OfferItem extends Model {
   id!: number;
   formData!: string[];
   /*...rest of the attributes...*/

   /*....*/
}
Enter fullscreen mode Exit fullscreen mode

Or you can use the combination of both. Finally, it boils down to what are you trying to solve: transpiler warnings or having a definition of attribute type. 😄

Collapse
 
shockwavee profile image
Davor Tvorić

You're right! I've never thought of this before.
I like the second solution you provided, it is a lot like defining a new interface, but at least you don't have to create a new file each time.
The first solution is kind of defeating the purpose, but as you said, it's a matter of what you're solving.

Thanks for your input and I'll definitely utilize your solution!