@@ -51,6 +51,88 @@ User.instanceDefaults = function() {
51
51
}
52
52
```
53
53
54
+ ### BaseModel typing <Badge text =" 3.11.0+ " />
55
+
56
+ Version ` 3.11.0 ` brings explicit typing to the BaseModel. This gives helpful IDE autocomplete and errors when Model classes or instances
57
+ are used incorrectly.
58
+
59
+ One major change here is that the BaseModel now enforces Vuex strict mode compliance by default and encourages proper state management using
60
+ the clone and commit pattern. It does this by declaring the underlying model data ` readonly ` . This means the TS compiler will error at any
61
+ attempt to directly assign to a model.
62
+
63
+ Take the ` User ` class from above
64
+
65
+ ``` ts
66
+ // wrong
67
+ const user = new User ()
68
+ user .
email = ' [email protected] ' // <- TS will error here
69
+ ```
70
+
71
+ The proper way to edit an existing ` User ` instance is to clone it, edit the * clone's* props, and then commit the changes.
72
+ This ensures changes don't propagate to the rest of the app until ready.
73
+
74
+ ``` ts
75
+ // correct
76
+ const clone = user .clone ()
77
+ clone .
email = ' [email protected] ' // <- No error here
78
+ clone .commit ()
79
+ ```
80
+
81
+ You can disable this ` readonly ` behavior if desired. In ` feathers-client.ts ` , augment FeathersVuex's typing
82
+
83
+ ``` ts
84
+ declare module ' feathers-vuex' {
85
+ interface FeathersVuexTypeOptions {
86
+ ' model-readonly' : false
87
+ }
88
+ }
89
+ ```
90
+
91
+ ### Casting the BaseModel <Badge text =" 3.11.0+ " />
92
+
93
+ Typescript users can further enhance typing on Model classes and instances by passing their data's underlying structure as an interface
94
+ to ` castBaseModel<T>() ` . This gives helpful type hints and autocomplete from your IDE when interacting with your underlying Model data.
95
+
96
+ To take advantage of this, first we need to update ` feathers-client.ts ` to export the new function
97
+
98
+ ``` ts
99
+ // feathers-client.ts
100
+ const {/* other props, */ castBaseModel } = feathersVuex (/* ... */ )
101
+
102
+ // Export `castBaseModel` too
103
+ export { /* other props */ castBaseModel }
104
+ ```
105
+
106
+ Now we can use ` castBaseModel() ` when defining our Model class
107
+
108
+ ``` ts
109
+ import feathersClient , { makeServicePlugin , castBaseModel } from ' ../feathers-client'
110
+
111
+ // Define an interface for your underlying data
112
+ interface UserData {
113
+ id: number
114
+ email: string
115
+ password: string
116
+ }
117
+
118
+ // Pass interface to castBaseModel()
119
+ class TypedUser extends castBaseModel <UserData >() {
120
+ static readonly modelName = ' TypedUser'
121
+ }
122
+
123
+ // Make the plugin just as before
124
+ const servicePath = ' users'
125
+ const servicePlugin = makeServicePlugin ({
126
+ Model: TypedUser ,
127
+ service: feathersClient .service (servicePath ),
128
+ servicePath
129
+ })
130
+ ```
131
+
132
+ Now our IDE knows that instances of ` TypedUser ` have all props defined by the ` UserData ` interface.
133
+
134
+ By default, the BaseModel uses ` { [key: string]: any } ` as the underlying data interface meaning any prop can be accessed/assigned to.
135
+
54
136
## Model attributes
55
137
56
138
The following attributes are available on each model:
0 commit comments