feathers icon indicating copy to clipboard operation
feathers copied to clipboard

infer `multi`, `id` & `paginate` of `service.options`

Open fratzinger opened this issue 2 years ago • 4 comments
trafficstars

Problem:

  • For all services the type of data for create is T or T[], even true for services with multi: false / multi: { create: false }.
  • For all services the type of id for patch & remove is NullableId, even for services with multi: false / multi: { patch: false, remove: false }
  • For all services the awaited return type of find is Result[] | Paginated<Result>, even for services with paginate: false
  • { $select: ['email'] } does not return Pick<Result, 'email'> but the 'full' type Result instead. Even though Pick<Result, 'email'> wouldn't be the correct type either. It has to be Pick<Result, 'email' | Service['options']['id']>

The root of these problems above is, that the type of service.options is not considered in the service methods. The AdapterBase already has a generic Options. We only need to infer the type and fall back to the general types, if it cannot infer.

Other things to consider:

es6 classes are tedious to work with for heavy TS work like inference. We already saw this for feathers-pinia and moved away from model classes. I think we should move away from es6 classes for adapters & services and make a custom useService(...) function. But I guess I need to open another issue/discussion for this.

fratzinger avatar Jan 27 '23 09:01 fratzinger

This is interesting - I made a question on discord about the return type of the find method and how to handle it. ( https://discord.com/channels/509848480760725514/1062772689913266216/1062772689913266216 ). If the service return type "understood" the pagination property it would make (my!) code much much neater! There might be a better way to handle it currently but it would be great to have this type inference!

mrobst avatar Jan 27 '23 10:01 mrobst

I noticed using the v5/Dove client that the return type is correct and changes according to the use of paginate:false. This is great!

mrobst avatar Feb 06 '23 11:02 mrobst

Yes, that's true, if you do find({ paginate: false }) explicitely. That catches 80% but is not the point of this issue. When you don't use it explicitely as in find({ query: { ... } }) the returned type is T[] | Paginated<T>.

fratzinger avatar Feb 06 '23 11:02 fratzinger

data for create is T or T[]

This is actually the correct type for a before hook, the validation step for multi isn't done until the database adapter. So technically a create before hook may receive array type data.

AshotN avatar Oct 06 '23 13:10 AshotN