Skip to content

Commit 454abe4

Browse files
committed
pare down base model typing to non-generic
1 parent 353f68c commit 454abe4

File tree

6 files changed

+57
-85
lines changed

6 files changed

+57
-85
lines changed

src/index.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,13 @@ import useGet from './useGet'
2121
import {
2222
FeathersVuexOptions,
2323
HandleEvents,
24+
Model,
2425
ModelStatic,
2526
ModelSetupContext,
26-
Model,
2727
Id,
2828
FeathersVuexStoreState,
2929
FeathersVuexGlobalModels,
30-
FeathersVuexTypeOptions,
3130
GlobalModels,
32-
ModelInstance
3331
} from './service-module/types'
3432
import { initAuth, hydrateApi } from './utils'
3533
import { FeathersVuex } from './vue-plugin/vue-plugin'
@@ -85,7 +83,6 @@ export default function feathersVuex(feathers, options: FeathersVuexOptions) {
8583
return {
8684
makeServicePlugin,
8785
BaseModel: BaseModel as ModelStatic,
88-
castBaseModel: <T extends {} = {}>() => BaseModel as ModelStatic<T>,
8986
makeAuthPlugin,
9087
FeathersVuex,
9188
models: models as GlobalModels,
@@ -112,10 +109,8 @@ export {
112109
Id,
113110
Model,
114111
ModelStatic,
115-
ModelInstance,
116112
ModelSetupContext,
117113
ServiceState,
118114
FeathersVuexGlobalModels,
119115
FeathersVuexStoreState,
120-
FeathersVuexTypeOptions
121116
}

src/service-module/make-base-model.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {
1111
ModelStatic,
1212
GlobalModels,
1313
StoreState,
14-
ModelInstance,
1514
AnyData
1615
} from './types'
1716
import { globalModels, prepareAddModel } from './global-models'
@@ -59,23 +58,23 @@ export default function makeBaseModel(options: FeathersVuexOptions) {
5958
// If this serverAlias already has a BaseModel, return it
6059
const ExistingBaseModel = _get(globalModels, `[${serverAlias}].BaseModel`)
6160
if (ExistingBaseModel) {
62-
return ExistingBaseModel as ModelStatic<AnyData>
61+
return ExistingBaseModel as ModelStatic
6362
}
6463

65-
abstract class BaseModel implements ModelInstance<AnyData> {
64+
abstract class BaseModel implements Model {
6665
// Think of these as abstract static properties
6766
public static servicePath: string
6867
public static namespace: string
6968
public static keepCopiesInStore = options.keepCopiesInStore
7069
// eslint-disable-next-line
71-
public static instanceDefaults(data: Partial<AnyData>, ctx: ModelSetupContext) {
70+
public static instanceDefaults(data: AnyData, ctx: ModelSetupContext) {
7271
return data
7372
}
7473
// eslint-disable-next-line
75-
public static setupInstance(data: Partial<AnyData>, ctx: ModelSetupContext) {
74+
public static setupInstance(data: AnyData, ctx: ModelSetupContext) {
7675
return data
7776
}
78-
public static diffOnPatch(data: Partial<AnyData>) {
77+
public static diffOnPatch(data: AnyData) {
7978
return data
8079
}
8180

@@ -89,8 +88,8 @@ export default function makeBaseModel(options: FeathersVuexOptions) {
8988

9089
public static readonly models = globalModels as GlobalModels // Can access other Models here
9190
public static copiesById: {
92-
[key: string]: Model<AnyData> | undefined
93-
[key: number]: Model<AnyData> | undefined
91+
[key: string]: Model | undefined
92+
[key: number]: Model | undefined
9493
} = {}
9594

9695
public __id: string
@@ -100,7 +99,7 @@ export default function makeBaseModel(options: FeathersVuexOptions) {
10099
public static merge = mergeWithAccessors
101100
public static modelName = 'BaseModel'
102101

103-
public constructor(data: Partial<AnyData>, options: ModelInstanceOptions) {
102+
public constructor(data: AnyData, options: ModelInstanceOptions) {
104103
// You have to pass at least an empty object to get a tempId.
105104
data = data || {}
106105
options = Object.assign({}, defaultOptions, options)
@@ -268,7 +267,7 @@ export default function makeBaseModel(options: FeathersVuexOptions) {
268267
/**
269268
* clone the current record using the `createCopy` mutation
270269
*/
271-
public clone(data: Partial<AnyData>): this {
270+
public clone(data: AnyData): this {
272271
const { idField, tempIdField } = this.constructor as typeof BaseModel
273272
if (this.__isClone) {
274273
throw new Error('You cannot clone a copy')
@@ -428,5 +427,5 @@ export default function makeBaseModel(options: FeathersVuexOptions) {
428427

429428
const BaseModelEventEmitter = BaseModel
430429
assertIsEventEmitter(BaseModelEventEmitter)
431-
return BaseModelEventEmitter as ModelStatic<AnyData>
430+
return BaseModelEventEmitter as ModelStatic
432431
}

src/service-module/service-module.state.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export interface ServiceStateExclusiveDefaults {
3737
modelName?: string
3838
}
3939

40-
export interface ServiceState<D extends AnyData = AnyData> {
40+
export interface ServiceState<M extends Model = Model> {
4141
options: {}
4242
ids: string[]
4343
autoRemove: boolean
@@ -56,15 +56,15 @@ export interface ServiceState<D extends AnyData = AnyData> {
5656
idField: string
5757
tempIdField: string
5858
keyedById: {
59-
[k: string]: Model<D>
60-
[k: number]: Model<D>
59+
[k: string]: M
60+
[k: number]: M
6161
}
6262
tempsById: {
63-
[k: string]: Model<D>
64-
[k: number]: Model<D>
63+
[k: string]: M
64+
[k: number]: M
6565
}
6666
copiesById: {
67-
[k: string]: Model<D>
67+
[k: string]: M
6868
}
6969
whitelist: string[]
7070
paramsForServer: string[]

src/service-module/types.ts

Lines changed: 17 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -114,31 +114,10 @@ export interface ModelInstanceOptions {
114114
merge?: boolean
115115
}
116116

117-
export type AnyData = { [k: string]: any }
118-
119-
// eslint-disable-next-line @typescript-eslint/no-empty-interface
120-
export interface FeathersVuexTypeOptions {
121-
// 'model-readonly': true
122-
}
123-
124-
type GetOption<T, K, Default = false> = K extends keyof T ? T[K] : Default
125-
126-
// ModelData is readonly unless user explicitly says `model-readonly` is false
127-
type ModelData<D> = GetOption<
128-
FeathersVuexTypeOptions,
129-
'model-readonly',
130-
true
131-
> extends false
132-
? D
133-
: Readonly<D>
134-
135-
/**
136-
* FeathersVuex Model with readonly data props
137-
*/
138-
export type Model<D extends {} = AnyData> = ModelInstance<D> & ModelData<D>
117+
export type AnyData = { [key: string]: any }
139118

140119
/** Static Model interface */
141-
export interface ModelStatic<D extends {} = AnyData> extends EventEmitter {
120+
export interface ModelStatic extends EventEmitter {
142121
/**
143122
* The path passed to `FeathersClient.service()` to create the service
144123
*/
@@ -181,8 +160,8 @@ export interface ModelStatic<D extends {} = AnyData> extends EventEmitter {
181160
* All model copies created using `model.clone()`
182161
*/
183162
readonly copiesById: {
184-
[key: string]: Model<D> | undefined
185-
[key: number]: Model<D> | undefined
163+
[key: string]: Model | undefined
164+
[key: number]: Model | undefined
186165
}
187166

188167
/**
@@ -215,8 +194,8 @@ export interface ModelStatic<D extends {} = AnyData> extends EventEmitter {
215194
* @param data partial model data
216195
* @param options model instance options
217196
*/
218-
new (data?: Partial<D>, options?: ModelInstanceOptions): Model<D>
219-
prototype: Model<D>
197+
new (data?: AnyData, options?: ModelInstanceOptions): Model
198+
prototype: Model
220199

221200
/**
222201
* The instanceDefaults API was created in version 1.7 to prevent
@@ -230,7 +209,7 @@ export interface ModelStatic<D extends {} = AnyData> extends EventEmitter {
230209
* @param data the instance data
231210
* @param ctx setup context
232211
*/
233-
instanceDefaults(data: Partial<D>, ctx: ModelSetupContext): Partial<D>
212+
instanceDefaults(data: AnyData, ctx: ModelSetupContext): AnyData
234213

235214
/**
236215
* A new setupInstance class method is now available in version 2.0.
@@ -241,7 +220,7 @@ export interface ModelStatic<D extends {} = AnyData> extends EventEmitter {
241220
* @param data the instance data
242221
* @param ctx setup context
243222
*/
244-
setupInstance(data: Partial<D>, ctx: ModelSetupContext): Partial<D>
223+
setupInstance(data: AnyData, ctx: ModelSetupContext): AnyData
245224

246225
/**
247226
* Gets called just before sending the data to the API server. It gets
@@ -250,35 +229,36 @@ export interface ModelStatic<D extends {} = AnyData> extends EventEmitter {
250229
* Default: `data => data`
251230
* @param data the instance data
252231
*/
253-
diffOnPatch(data: Partial<D>): Partial<D>
232+
diffOnPatch(data: AnyData): AnyData
254233

255234
/**
256235
* A proxy for the `find` action
257236
* @param params Find params
258237
*/
259-
find(params?: Params): Promise<Model<D>[] | Paginated<Model<D>>>
238+
find<M extends Model = Model>(params?: Params): Promise<M[] | Paginated<M>>
260239
/**
261240
* A proxy for the `find` getter
262241
* @param params Find params
263242
*/
264-
findInStore(params?: Params): Paginated<Model<D>>
243+
findInStore<M extends Model = Model>(params?: Params): Paginated<M>
265244

266245
/**
267246
* A proxy for the `get` action
268247
* @param id ID of record to retrieve
269248
* @param params Get params
270249
*/
271-
get(id: Id, params?: Params): Promise<Model<D> | undefined>
250+
get<M extends Model = Model>(id: Id, params?: Params): Promise<M | undefined>
272251
/**
273252
* A proxy for the `get` getter
274253
* @param id ID of record to retrieve
275254
* @param params Get params
276255
*/
277-
getFromStore(id: Id, params?: Params): Model<D> | undefined
256+
getFromStore<M extends Model = Model>(id: Id, params?: Params): M | undefined
278257
}
279258

280259
/** Model instance interface */
281-
export interface ModelInstance<D extends {} = AnyData> {
260+
export interface Model {
261+
[key: string]: any
282262
/**
283263
* model's temporary ID
284264
*/
@@ -298,7 +278,7 @@ export interface ModelInstance<D extends {} = AnyData> {
298278
* commit or save the data.
299279
* @param data Properties to modify on the cloned instance
300280
*/
301-
clone(data?: Partial<D>): this
281+
clone(data?: AnyData): this
302282
/**
303283
* The create method calls the create action (service method)
304284
* using the instance data.
@@ -315,7 +295,7 @@ export interface ModelInstance<D extends {} = AnyData> {
315295
* with partial data.
316296
* @param params Params passed to the Feathers client request
317297
*/
318-
patch(params?: PatchParams<D>): Promise<this>
298+
patch<D extends {} = AnyData>(params?: PatchParams<D>): Promise<this>
319299
/**
320300
* The remove method calls the remove action (service method)
321301
* using the instance data. The instance's id field is used

src/useFind.ts

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ import {
1111
watch
1212
} from '@vue/composition-api'
1313
import debounce from 'lodash/debounce'
14-
import { getItemsFromQueryInfo, getQueryInfo, Params } from './utils'
14+
import { getItemsFromQueryInfo, getQueryInfo, Params, Paginated } from './utils'
1515
import { AnyData, ModelStatic, Model } from './service-module/types'
1616

17-
interface UseFindOptions<T> {
18-
model: ModelStatic<T>
17+
interface UseFindOptions {
18+
model: ModelStatic
1919
params: Params | Ref<Params>
2020
fetchParams?: Params | Ref<Params>
2121
queryWhen?: Ref<boolean>
@@ -33,8 +33,8 @@ interface UseFindState {
3333
latestQuery: null | object
3434
isLocal: boolean
3535
}
36-
interface UseFindData<T> {
37-
items: Ref<Readonly<Model<T>[]>>
36+
interface UseFindData<M> {
37+
items: Ref<Readonly<M[]>>
3838
servicePath: Ref<string>
3939
isPending: Ref<boolean>
4040
haveBeenRequested: Ref<boolean>
@@ -45,14 +45,14 @@ interface UseFindData<T> {
4545
latestQuery: Ref<object>
4646
paginationData: Ref<object>
4747
error: Ref<Error>
48-
find: Function
48+
find(params: Params | Ref<Params>): Promise<M[] | Paginated<M>>
4949
}
5050

5151
const unwrapParams = (params: Params | Ref<Params>): Params =>
5252
isRef(params) ? params.value : params
5353

54-
export default function find<T extends AnyData = AnyData>(options: UseFindOptions<T>): UseFindData<T> {
55-
const defaults: UseFindOptions<T> = {
54+
export default function find<M extends Model = Model>(options: UseFindOptions): UseFindData<M> {
55+
const defaults: UseFindOptions = {
5656
model: null,
5757
params: null,
5858
qid: 'default',
@@ -95,7 +95,7 @@ export default function find<T extends AnyData = AnyData>(options: UseFindOption
9595
})
9696
const computes = {
9797
// The find getter
98-
items: computed<Model<T>[]>(() => {
98+
items: computed<M[]>(() => {
9999
const getterParams = unwrapParams(params)
100100

101101
if (getterParams && getterParams.paginate) {
@@ -114,8 +114,7 @@ export default function find<T extends AnyData = AnyData>(options: UseFindOption
114114
)
115115
return items
116116
} else {
117-
const found = model.findInStore(getterParams)
118-
return Array.isArray(found) ? found : found.data
117+
return model.findInStore<M>(getterParams).data
119118
}
120119
}),
121120
paginationData: computed(() => {
@@ -124,17 +123,16 @@ export default function find<T extends AnyData = AnyData>(options: UseFindOption
124123
servicePath: computed<string>(() => model.servicePath)
125124
}
126125

127-
function find(params: Params | Ref<Params>) {
126+
function find(params: Params | Ref<Params>): Promise<M[] | Paginated<M>> {
128127
params = unwrapParams(params)
129128
if (queryWhen.value && !state.isLocal) {
130129
state.isPending = true
131130
state.haveBeenRequested = true
132131

133-
return model.find(params).then(response => {
132+
return model.find<M>(params).then(response => {
134133
// To prevent thrashing, only clear error on response, not on initial request.
135134
state.error = null
136135
state.haveLoaded = true
137-
138136
if(!Array.isArray(response)) {
139137
const queryInfo = getQueryInfo(params, response)
140138
queryInfo.response = response

0 commit comments

Comments
 (0)