Skip to content

Commit 227d4e8

Browse files
committed
docs: update for simplified non-generic interfaces
1 parent 31cf7a7 commit 227d4e8

File tree

2 files changed

+61
-57
lines changed

2 files changed

+61
-57
lines changed

docs/composition-api.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,21 @@ export default new Router({
779779

780780
Now, the `Post.vue` file only requires to have a `prop` named `id`. Vue Router will pass the params from the route as props to the component. See the [first useGet example](#useget) for a component that would work with the above route. The vue-router documentation has more information about [Passing Props to Route Components](https://router.vuejs.org/guide/essentials/passing-props.html#passing-props-to-route-components)
781781

782+
### Composing with Model types
783+
784+
Both `useGet` and `useFind` have an optional type parameter for the Model type which is used as the type for the returned item(s).
785+
786+
```ts
787+
// Destructure Model class from global models object
788+
const { User } = Vue.$FeathersVuex.api
789+
790+
// use useGet with User Model
791+
useGet<typeof User.prototype>(/* ... */)
792+
793+
// use useFind with User Model
794+
useFind<typeof User.prototype>(/* ... */)
795+
```
796+
782797
## Conventions for Development
783798

784799
### Params are Computed

docs/model-classes.md

Lines changed: 46 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ While [setting up Feathers-Vuex](/getting-started.html#feathers-client-feathers-
1515
```js
1616
import feathersClient, { makeServicePlugin, BaseModel } from '../feathers-client'
1717

18-
class User extends BaseModel {
18+
export class User extends BaseModel {
1919
// Required for $FeathersVuex plugin to work after production transpile.
2020
static modelName = 'User'
2121
// Define default properties here
@@ -53,85 +53,74 @@ User.instanceDefaults = function() {
5353

5454
### BaseModel typing <Badge text="3.11.0+" />
5555

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.
56+
Version `3.11.0` brings explicit typing to the BaseModel. This gives helpful IDE autocomplete and errors when using Model classes.
5857

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.
58+
Since Feathers-Vuex doesn't know what your data looks like, you will need to help define your underlying model data's interface.
6259

63-
Take the `User` class from above
60+
By default, Model classes are `string` indexable with value of type `any`. This isn't super helpful...
6461

6562
```ts
66-
// wrong
67-
const user = new User()
68-
user.email = '[email protected]' // <- TS will error here
63+
// Just like before, we define our class as an extension of BaseModel
64+
export class User extends BaseModel { /* ... */ }
65+
66+
// Augment the User Model interface
67+
export interface User {
68+
email: string
69+
password: string
70+
}
6971
```
7072

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+
Now, whenever we access a `User` model, all fields defined in the interface will be available in IDE auto-complete/intellisense along with the model methods/props.
74+
75+
If you already have a User interface defined under a different name, just define a new interface with the same name as your Model class like so
7376

7477
```ts
75-
// correct
76-
const clone = user.clone()
77-
clone.email = '[email protected]' // <- No error here
78-
clone.commit()
78+
// if our User interface already exists as UserRecord
79+
export interface User extends UserRecord {}
7980
```
8081

81-
You can disable this `readonly` behavior if desired. In `feathers-client.ts`, augment FeathersVuex's typing
82+
To further enhance typing, you can augment FeathersVuex types to aid development in other parts of your app. It's important to note the differences in the following example if you do or do not setup a `serverAlias`.
8283

8384
```ts
84-
declare module 'feathers-vuex' {
85-
interface FeathersVuexTypeOptions {
86-
'model-readonly': false
87-
}
88-
}
89-
```
85+
// src/store/user.store.ts
86+
import { ServiceState } from 'feathers-vuex'
9087

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.
88+
export class User extends BaseModel { /* ... */ }
89+
export interface User { /* ... */ }
90+
const servicePath = 'users'
9591

96-
To take advantage of this, first we need to update `feathers-client.ts` to export the new function
92+
declare module "feathers-vuex" {
93+
interface FeathersVuexStoreState {
94+
[servicePath]: ServiceState<User>
95+
}
9796

98-
```ts
99-
// feathers-client.ts
100-
const {/* other props, */ castBaseModel } = feathersVuex(/* ... */)
97+
// Only if you setup FeathersVuex without a serverAlias!!
98+
interface FeathersVuexGlobalModels {
99+
User: typeof User
100+
}
101+
}
101102

102-
// Export `castBaseModel` too
103-
export { /* other props */ castBaseModel }
103+
// Only if you setup FeathersVuex with a serverAlias!!
104+
declare module "src/store" {
105+
interface MyApiModels {
106+
User: typeof User
107+
}
108+
}
104109
```
105110

106-
Now we can use `castBaseModel()` when defining our Model class
111+
If you have setup a `serverAlias`, you need to add the following to `src/store/index.ts`.
107112

108113
```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'
114+
// src/store/index.ts
115+
export interface MyApiModels { /* Let each service augment this interface */ }
116+
declare module "feathers-vuex" {
117+
interface FeathersVuexGlobalModels {
118+
'my-api-name': MyApiModels
119+
}
121120
}
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-
})
130121
```
131122

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.
123+
Replace `my-api-name` with the `serverAlias` you used when setting up FeathersVuex.
135124

136125
## Model attributes
137126

0 commit comments

Comments
 (0)