Feathers-vuex: TypeScript helpers suggestion.

Created on 20 Apr 2018  Â·  11Comments  Â·  Source: feathersjs-ecosystem/feathers-vuex

Hello,

I have used feathers-vuex with TypeScript in a project and I made a set of helpers that I think could be really useful to other developers, here you can see the source code and below is an example of usage:

import Vue from 'vue'
import { Component } from 'vue-property-decorator'
import { namespace, Action } from 'vuex-class'
import { ActionGet, ActionCreate, ActionPatch } from '../types/feathers'
import { Person } from '../types/models'

const PeopleAction = namespace('people', Action)

@Component
export default class CreateEditPeople extends Vue {
  @PeopleAction('get') getPerson: ActionGet<Person>
  @PeopleAction('create') createPerson: ActionCreate<Person>
  @PeopleAction('patch') patchPerson: ActionPatch<Person>
  // some extra here
}

TypeScript reads it really well and all suggestions and autocomplete helps a lot.

documentation

Most helpful comment

I have some typings for feathers-vuex too, I'm planning on putting together a PR at some point, but for now here they are.

Updated 7/30/19

import { Application, Query, Params } from "@feathersjs/feathers";
import { StoreOptions, Plugin, Commit, Dispatch, Store } from "vuex";
import Vue, { PluginObject, ComponentOptions } from "vue";
import { Request } from "request";
import { PropsDefinition } from "vue/types/options";

/**
 * default export
 */
declare const FeathersVuexDefault: (client: Application, options: Partial<FeathersVuexOptions>) => FeathersVuexResult;
export default FeathersVuexDefault;

interface FeathersVuexResult {
  service<ModelType = any, IDType = string>(servicePath: string, options?: Partial<FeathersVuexOptions>): Plugin<FeathersVuexServiceState<ModelType, IDType>>;
  auth<UserType>(options?: FeathersVuexAuthOptions): Plugin<FeathersVuexAuthState<UserType>>;
  FeathersVuex: PluginObject<any>;
}

interface FeathersVuexCoreProps {
  /**
   * @default 'id'
   */
  idField: string;
  /**
   * @default false
   */
  autoRemove: boolean;
  /**
   * @default true
   */
  enableEvents: boolean;
  /**
   * @default false
   */
  addOnUpsert: boolean;
  /**
   * @default false
   */
  diffOnPatch: boolean;
  /**
   * @default false
   */
  skipRequestIfExists: boolean;
  /**
   * @default false
   */
  preferUpdate: boolean;
  /**
   * @default false
   */
  replaceItems: boolean;
}
interface FeathersVuexStoreOptions<Store> extends Pick<StoreOptions<Store>, 'state' | 'getters' | 'mutations' | 'actions'> { }

interface FeathersVuexOptions<Store = any> extends FeathersVuexStoreOptions<Store>, FeathersVuexCoreProps {

  /**
   * @default 'path'
   */
  nameStyle?: 'short' | 'path';
  namespace: string;
  apiPrefix: string
  modelName: string;
  instanceDefaults?: any;
  /**
   * @debug false
   */
  debug: boolean;
}

/**
 * Service Model
 */

// This is an interface because it needs to return FeathersVuexModelClass & T
// from the constructor, which isn't allowed with classes
interface FeathersVuexModelClass<ModelType = any> {
  namespace: string;
  className: string;
  modelName: string;
  store: Store<any>; // todo: Type the VuexStore so we can include it here
  options: FeathersVuexOptions;
  new(data?: Partial<ModelType>, options?: FeathersVuexModelOptions): FeathersVuexModel<ModelType>;
  create: (params?: GetParams) => Promise<FeathersVuexModel<ModelType>>;
  save: (params?: GetParams) => Promise<FeathersVuexModel<ModelType>>;
  patch: (params?: GetParams) => Promise<FeathersVuexModel<ModelType>>;
  update: (params?: GetParams) => Promise<FeathersVuexModel<ModelType>>;
  clone: () => Promise<FeathersVuexModel<ModelType>>;
  reset: () => Promise<FeathersVuexModel<ModelType>>;
  remove: (params?: GetParams) => Promise<FeathersVuexModel<ModelType>>;
}

export type FeathersVuexModel<T> = FeathersVuexModelClass<T> & T;

type GetParams = Exclude<Params, 'paginate'>;
type FindParams = Params;

interface FeathersVuexModelOptions {
  isClone?: boolean;
  skipCommit?: boolean;
}

interface ModelStatic<T> {
  new(data?: Partial<T>, options?: FeathersVuexModelOptions): FeathersVuexModel<T>;
  find: (params?: FindParams) => FeathersVuexModel<T>[];
  findInStore: (params?: FindParams) => FeathersVuexModel<T>[];
  get: (id: any, params?: GetParams) => FeathersVuexModel<T>[];
  getFromStore: (id: any, params?: GetParams) => FeathersVuexModel<T>[];
}

/**
 * Vue Plugin
 */
type FeathersVuexGlobalModelsIndex<T> = {
  [P in keyof T]: {
    new(data?: Partial<T[P]>, options?: FeathersVuexModelOptions): FeathersVuexModel<T[P]>;
    find: (params?: FindParams) => FeathersVuexModel<T[P]>[];
    findInStore: (params?: FindParams) => FeathersVuexModel<T[P]>[];
    get: (id: any, params?: GetParams) => FeathersVuexModel<T[P]>[];
    getFromStore: (id: any, params?: GetParams) => FeathersVuexModel<T[P]>[];
  }
}


// This doesn't work because merging this into a string signature isn't a valid type
// Leaving it here so that hopefully someone can figure it out in the future
// type FeathersVuexGlobalModelsByPath<T> = {
//   byServicePath: FeathersVuexGlobalModelsIndex<T>
// }

/**
 * @description The type for the $FeathersVuex vue plugin. To type this stronger include the
 * following in a typings.d.ts file
 *
 *
 * @example
 * declare module "vue/types/vue" {
 *   import { FeathersVuexGlobalModels } from "feathers-vuex";
 *   interface Vue {
 *     $FeathersVuex: FeathersVuexGlobalModels<Services>;
 *   }
 * }
 *
 * @description Where services is something like this
 * @example
 * interface Services {
 *   users: User
 *   //...
 * }
 *
 * interface User {
 *   name: string;
 *   rating: number;
 *   //...
 * }
 *
 */
export type FeathersVuexGlobalModels<T = any, P = any> = FeathersVuexGlobalModelsIndex<T> // & FeathersVuexGlobalModelsByPath<P>; // See comment above

/**
 * Add FeathersVuex to the Vue prototype
 */
declare module "vue/types/vue" {
  interface FeathersVuexPluginType extends FeathersVuexGlobalModels { }

  interface Vue {
    $FeathersVuex: FeathersVuexPluginType;
  }
}

/**
 * Auth module factory
 */
interface FeathersVuexAuthOptions<State = FeathersVuexAuthState> extends FeathersVuexStoreOptions<State> {
  userService: string
}

interface FeathersVuexAuthState<UserType = any> {
  accessToken?: string, // The JWT
  payload: Object, // The JWT payload

  isAuthenticatePending: boolean,
  isLogoutPending: boolean,

  errorOnAuthenticate: Error | undefined,
  errorOnLogout: Error | undefined,
  user: UserType
}

interface FeathersVuexServiceState<ModelType = any, IDType = string> extends FeathersVuexCoreProps {
  ids: IDType[],
  keyedById: {
    [i: string]: ModelType
  }, // A hash map, keyed by id of each item
  currentId?: IDType, // The id of the item marked as current
  copy?: ModelType, // A deep copy of the current item
  servicePath: string // The full service path
  paginate: boolean, // Indicates if pagination is enabled on the Feathers service.
  pagination: { [key: string]: ModelType[] }, // Indicates if pagination is enabled on the Feathers service.

  isFindPending: boolean,
  isGetPending: boolean,
  isCreatePending: boolean,
  isUpdatePending: boolean,
  isPatchPending: boolean,
  isRemovePending: boolean,

  errorOnfind: Error | undefined,
  errorOnGet: Error | undefined,
  errorOnCreate: Error | undefined,
  errorOnUpdate: Error | undefined,
  errorOnPatch: Error | undefined,
  errorOnRemove: Error | undefined
}

/**
 * Data Components
 */
// todo: use generic FeathersVuex*Computed
export const FeathersVuexFind: ComponentOptions<
  Vue,
  FeathersVuexFindData,
  FeathersVuexFindMethods,
  FeathersVuexFindComputed,
  PropsDefinition<FeathersVuexFindProps>,
  FeathersVuexFindProps>;

export const FeathersVuexGet: ComponentOptions<
  Vue,
  FeathersVuexGetData,
  FeathersVuexGetMethods,
  FeathersVuexGetComputed,
  PropsDefinition<FeathersVuexGetProps>,
  FeathersVuexGetProps>;

interface FeathersVuexFindData {
  isFindPending: boolean;
}

interface FeathersVuexGetMethods {
  findData(): Promise<void>;
  fetchData(): Promise<void>;
}

interface FeathersVuexFindComputed<T = any> {
  items: T[];
  scope: { [key: string]: any }
  pagination: { [key: string]: any }
}

interface FeathersVuexDataComponentProps {
  service: string;
  query?: any;
  queryWhen?: boolean | ((id: string, ...args: any[]) => boolean);
  fetchQuery: any;
  watch?: string | string[];
  local?: boolean;
  editScope?: (params: FeathersVuexEditScopeArgs) => { [key: string]: any };
}

interface FeathersVuexEditScopeArgs {
  item: any;
  isGetPending: boolean
}

interface FeathersVuexFindProps extends FeathersVuexDataComponentProps {
  qid?: string;
}

interface FeathersVuexGetData {
  isFindPending: boolean;
  isGetPending: boolean;
}
interface FeathersVuexFindMethods {
  getArgs(queryToUse?: Query): any[];
  getData(): Promise<void>;
  fetchData(): Promise<void>;
}
interface FeathersVuexGetComputed<T = any> {
  item: T | null;
  scope: { [key: string]: any }
}

interface FeathersVuexGetProps extends FeathersVuexDataComponentProps {
  id?: number | string;
}


/**
 * Utilities
 */
// todo: these mixins could probably have much better return types to make use of the generic
export function makeFindMixin<T = any>(options: MakeFindMixinOptions<T>): (ComponentOptions<Vue> | typeof Vue);
export function makeGetMixin<T = any>(options: MakeGetMixinOptions<T>): (ComponentOptions<Vue> | typeof Vue);

interface DataComponentOptions {
  /**
   * Service name, either service or name are required
   *
   * note: it looks like this can also be a function, but I don't quite understand the effects
   * so I'm not documenting it right now
   */
  service: string;
  /**
   * Service name, either service or name are required
   */
  name?: string;
  params?: Params;
  /**
   * @default () => true
   */
  queryWhen?: boolean | ((params: Params) => boolean);
  /**
   * @default false
   */
  local?: boolean;
  qid?: string | number | symbol;
  debug?: boolean;
  watch: string | boolean | string[];
}

interface MakeFindMixinOptions<T = any> extends DataComponentOptions {
  fetchQuery?: Query;
  items?: T[];
}
interface MakeGetMixinOptions<T = any> extends DataComponentOptions {
  fetchParams?: Params;
  id?: any;
  item?: T;
}


/**
 * Init Auth
 */
interface InitAuthOptions {
  commit: Commit;
  dispatch: Dispatch;
  req: Request;
  cookieName: string;
  moduleName: string;
  feathersClient: Application;
}
export function initAuth(options: InitAuthOptions): Promise<object>;


All 11 comments

Cool!

@nickmessing how would one use your feathers-vuex-helpers.ts file in their project? This looks like something that ought to go into the docs in a "Using with TypeScript" section. We can link to your helpers gist.

@marshallswain, I could finalize the typings and make a PR to make them universal so people can use them with bot class-component definition and classic component definition if you want to support that.

I know absolutely nothing about TypeScript, but I know that a lot of people
will appreciate this. I might even learn something, here, so I’d like to
support it, yeah. :) please make a PR when you have time. That would be
terrific!
On Sun, Apr 22, 2018 at 3:25 AM Nick Messing notifications@github.com
wrote:

@marshallswain https://github.com/marshallswain, I could finalize the
typings and make a PR to make them universal so people can use them with
bot class-component definition
https://gist.github.com/nickmessing/f206056cb0eb8879b068f727a1aaecbb
and classic component definition
https://gist.github.com/nickmessing/dfc8264ecc17d68ed5aaa82bd253d4e5 if
you want to support that.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/feathers-plus/feathers-vuex/issues/114#issuecomment-383367639,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAH3WTT3-Bo75lv1FXsC0p0WseLN8_0xks5trEx5gaJpZM4TcmIA
.

@rayfoss is your 👎 reaction a reflection of your dislike for TypeScript? Or is it about the quality of the recommendation?

@marshallswain Features should have a good reason to exist because they take time to add and maintain. My vote is just a reflection of this feature being 99% unlikely to be of use to me. I'm waiting for native types to come to Node. Fun fact, I used to use Typescript in Angular 2.

I think TS support is good for the project, as long as it doesn't get in the way for everybody else with a ton of irrelevant files and dependencies everywhere. Forcing it is definitely a bad idea, as there are many many hold outs and designers using js or flow. Remember coffeescript?

@rayfoss Thanks for the update. I have similar sentiment. If @nickmessing's suggestions work without requiring modifying the repo, that's the perfect solution, in my opinion.

I've added a link to this issue in the docs. I'm closing this issue, now. Thanks, guys.

I have some typings for feathers-vuex too, I'm planning on putting together a PR at some point, but for now here they are.

Updated 7/30/19

import { Application, Query, Params } from "@feathersjs/feathers";
import { StoreOptions, Plugin, Commit, Dispatch, Store } from "vuex";
import Vue, { PluginObject, ComponentOptions } from "vue";
import { Request } from "request";
import { PropsDefinition } from "vue/types/options";

/**
 * default export
 */
declare const FeathersVuexDefault: (client: Application, options: Partial<FeathersVuexOptions>) => FeathersVuexResult;
export default FeathersVuexDefault;

interface FeathersVuexResult {
  service<ModelType = any, IDType = string>(servicePath: string, options?: Partial<FeathersVuexOptions>): Plugin<FeathersVuexServiceState<ModelType, IDType>>;
  auth<UserType>(options?: FeathersVuexAuthOptions): Plugin<FeathersVuexAuthState<UserType>>;
  FeathersVuex: PluginObject<any>;
}

interface FeathersVuexCoreProps {
  /**
   * @default 'id'
   */
  idField: string;
  /**
   * @default false
   */
  autoRemove: boolean;
  /**
   * @default true
   */
  enableEvents: boolean;
  /**
   * @default false
   */
  addOnUpsert: boolean;
  /**
   * @default false
   */
  diffOnPatch: boolean;
  /**
   * @default false
   */
  skipRequestIfExists: boolean;
  /**
   * @default false
   */
  preferUpdate: boolean;
  /**
   * @default false
   */
  replaceItems: boolean;
}
interface FeathersVuexStoreOptions<Store> extends Pick<StoreOptions<Store>, 'state' | 'getters' | 'mutations' | 'actions'> { }

interface FeathersVuexOptions<Store = any> extends FeathersVuexStoreOptions<Store>, FeathersVuexCoreProps {

  /**
   * @default 'path'
   */
  nameStyle?: 'short' | 'path';
  namespace: string;
  apiPrefix: string
  modelName: string;
  instanceDefaults?: any;
  /**
   * @debug false
   */
  debug: boolean;
}

/**
 * Service Model
 */

// This is an interface because it needs to return FeathersVuexModelClass & T
// from the constructor, which isn't allowed with classes
interface FeathersVuexModelClass<ModelType = any> {
  namespace: string;
  className: string;
  modelName: string;
  store: Store<any>; // todo: Type the VuexStore so we can include it here
  options: FeathersVuexOptions;
  new(data?: Partial<ModelType>, options?: FeathersVuexModelOptions): FeathersVuexModel<ModelType>;
  create: (params?: GetParams) => Promise<FeathersVuexModel<ModelType>>;
  save: (params?: GetParams) => Promise<FeathersVuexModel<ModelType>>;
  patch: (params?: GetParams) => Promise<FeathersVuexModel<ModelType>>;
  update: (params?: GetParams) => Promise<FeathersVuexModel<ModelType>>;
  clone: () => Promise<FeathersVuexModel<ModelType>>;
  reset: () => Promise<FeathersVuexModel<ModelType>>;
  remove: (params?: GetParams) => Promise<FeathersVuexModel<ModelType>>;
}

export type FeathersVuexModel<T> = FeathersVuexModelClass<T> & T;

type GetParams = Exclude<Params, 'paginate'>;
type FindParams = Params;

interface FeathersVuexModelOptions {
  isClone?: boolean;
  skipCommit?: boolean;
}

interface ModelStatic<T> {
  new(data?: Partial<T>, options?: FeathersVuexModelOptions): FeathersVuexModel<T>;
  find: (params?: FindParams) => FeathersVuexModel<T>[];
  findInStore: (params?: FindParams) => FeathersVuexModel<T>[];
  get: (id: any, params?: GetParams) => FeathersVuexModel<T>[];
  getFromStore: (id: any, params?: GetParams) => FeathersVuexModel<T>[];
}

/**
 * Vue Plugin
 */
type FeathersVuexGlobalModelsIndex<T> = {
  [P in keyof T]: {
    new(data?: Partial<T[P]>, options?: FeathersVuexModelOptions): FeathersVuexModel<T[P]>;
    find: (params?: FindParams) => FeathersVuexModel<T[P]>[];
    findInStore: (params?: FindParams) => FeathersVuexModel<T[P]>[];
    get: (id: any, params?: GetParams) => FeathersVuexModel<T[P]>[];
    getFromStore: (id: any, params?: GetParams) => FeathersVuexModel<T[P]>[];
  }
}


// This doesn't work because merging this into a string signature isn't a valid type
// Leaving it here so that hopefully someone can figure it out in the future
// type FeathersVuexGlobalModelsByPath<T> = {
//   byServicePath: FeathersVuexGlobalModelsIndex<T>
// }

/**
 * @description The type for the $FeathersVuex vue plugin. To type this stronger include the
 * following in a typings.d.ts file
 *
 *
 * @example
 * declare module "vue/types/vue" {
 *   import { FeathersVuexGlobalModels } from "feathers-vuex";
 *   interface Vue {
 *     $FeathersVuex: FeathersVuexGlobalModels<Services>;
 *   }
 * }
 *
 * @description Where services is something like this
 * @example
 * interface Services {
 *   users: User
 *   //...
 * }
 *
 * interface User {
 *   name: string;
 *   rating: number;
 *   //...
 * }
 *
 */
export type FeathersVuexGlobalModels<T = any, P = any> = FeathersVuexGlobalModelsIndex<T> // & FeathersVuexGlobalModelsByPath<P>; // See comment above

/**
 * Add FeathersVuex to the Vue prototype
 */
declare module "vue/types/vue" {
  interface FeathersVuexPluginType extends FeathersVuexGlobalModels { }

  interface Vue {
    $FeathersVuex: FeathersVuexPluginType;
  }
}

/**
 * Auth module factory
 */
interface FeathersVuexAuthOptions<State = FeathersVuexAuthState> extends FeathersVuexStoreOptions<State> {
  userService: string
}

interface FeathersVuexAuthState<UserType = any> {
  accessToken?: string, // The JWT
  payload: Object, // The JWT payload

  isAuthenticatePending: boolean,
  isLogoutPending: boolean,

  errorOnAuthenticate: Error | undefined,
  errorOnLogout: Error | undefined,
  user: UserType
}

interface FeathersVuexServiceState<ModelType = any, IDType = string> extends FeathersVuexCoreProps {
  ids: IDType[],
  keyedById: {
    [i: string]: ModelType
  }, // A hash map, keyed by id of each item
  currentId?: IDType, // The id of the item marked as current
  copy?: ModelType, // A deep copy of the current item
  servicePath: string // The full service path
  paginate: boolean, // Indicates if pagination is enabled on the Feathers service.
  pagination: { [key: string]: ModelType[] }, // Indicates if pagination is enabled on the Feathers service.

  isFindPending: boolean,
  isGetPending: boolean,
  isCreatePending: boolean,
  isUpdatePending: boolean,
  isPatchPending: boolean,
  isRemovePending: boolean,

  errorOnfind: Error | undefined,
  errorOnGet: Error | undefined,
  errorOnCreate: Error | undefined,
  errorOnUpdate: Error | undefined,
  errorOnPatch: Error | undefined,
  errorOnRemove: Error | undefined
}

/**
 * Data Components
 */
// todo: use generic FeathersVuex*Computed
export const FeathersVuexFind: ComponentOptions<
  Vue,
  FeathersVuexFindData,
  FeathersVuexFindMethods,
  FeathersVuexFindComputed,
  PropsDefinition<FeathersVuexFindProps>,
  FeathersVuexFindProps>;

export const FeathersVuexGet: ComponentOptions<
  Vue,
  FeathersVuexGetData,
  FeathersVuexGetMethods,
  FeathersVuexGetComputed,
  PropsDefinition<FeathersVuexGetProps>,
  FeathersVuexGetProps>;

interface FeathersVuexFindData {
  isFindPending: boolean;
}

interface FeathersVuexGetMethods {
  findData(): Promise<void>;
  fetchData(): Promise<void>;
}

interface FeathersVuexFindComputed<T = any> {
  items: T[];
  scope: { [key: string]: any }
  pagination: { [key: string]: any }
}

interface FeathersVuexDataComponentProps {
  service: string;
  query?: any;
  queryWhen?: boolean | ((id: string, ...args: any[]) => boolean);
  fetchQuery: any;
  watch?: string | string[];
  local?: boolean;
  editScope?: (params: FeathersVuexEditScopeArgs) => { [key: string]: any };
}

interface FeathersVuexEditScopeArgs {
  item: any;
  isGetPending: boolean
}

interface FeathersVuexFindProps extends FeathersVuexDataComponentProps {
  qid?: string;
}

interface FeathersVuexGetData {
  isFindPending: boolean;
  isGetPending: boolean;
}
interface FeathersVuexFindMethods {
  getArgs(queryToUse?: Query): any[];
  getData(): Promise<void>;
  fetchData(): Promise<void>;
}
interface FeathersVuexGetComputed<T = any> {
  item: T | null;
  scope: { [key: string]: any }
}

interface FeathersVuexGetProps extends FeathersVuexDataComponentProps {
  id?: number | string;
}


/**
 * Utilities
 */
// todo: these mixins could probably have much better return types to make use of the generic
export function makeFindMixin<T = any>(options: MakeFindMixinOptions<T>): (ComponentOptions<Vue> | typeof Vue);
export function makeGetMixin<T = any>(options: MakeGetMixinOptions<T>): (ComponentOptions<Vue> | typeof Vue);

interface DataComponentOptions {
  /**
   * Service name, either service or name are required
   *
   * note: it looks like this can also be a function, but I don't quite understand the effects
   * so I'm not documenting it right now
   */
  service: string;
  /**
   * Service name, either service or name are required
   */
  name?: string;
  params?: Params;
  /**
   * @default () => true
   */
  queryWhen?: boolean | ((params: Params) => boolean);
  /**
   * @default false
   */
  local?: boolean;
  qid?: string | number | symbol;
  debug?: boolean;
  watch: string | boolean | string[];
}

interface MakeFindMixinOptions<T = any> extends DataComponentOptions {
  fetchQuery?: Query;
  items?: T[];
}
interface MakeGetMixinOptions<T = any> extends DataComponentOptions {
  fetchParams?: Params;
  id?: any;
  item?: T;
}


/**
 * Init Auth
 */
interface InitAuthOptions {
  commit: Commit;
  dispatch: Dispatch;
  req: Request;
  cookieName: string;
  moduleName: string;
  feathersClient: Application;
}
export function initAuth(options: InitAuthOptions): Promise<object>;


@NickBolles I just removed my client side project that used TypeScript, just to regenerate it as a JavaScript project.

Steps I tried to add typings to feathers-vuex:

  • Check if a @types/feathers-vuex definition exist, it does not.
  • Add my own typings directory to 'typeRoots' in tsconfig, specify a directory with the name feathers-vuex, with in it a index.d.ts with your code in it.
  • Renamed the 'declare module 'vue/types/vue' in your file to 'feathers-vuex' since that is what the cli told me to do (create a .d.ts file with a 'declare module "feathers-vuex";' in it. I then get an error that it can not be augmented. I delete all the code above 'declare module "vue/types/vue" in your file (which is "feathers-vuex" in my file). Then the error goes away. But it would still not recognize the typings.

Finally, I did what I said in the beginning and removed TypeScript just so I can follow along with a tutorial using this library.

@bartduisters There are probably other ways to achieve this without built in typings (which I believe are coming in v2), but here's how I have it setup

I have a folder @types/feathers-vuex with an index.d.ts in it with that content from my post above (which I just updated). Then I have a file @types/feathers-vuex-app.d.ts with the following content in it.

import { Services } from "../store";
import { FeathersVuexGlobalModels } from "feathers-vuex";

declare module "vue/types/vue" {
  interface FeathersVuexPluginType extends FeathersVuexGlobalModels<Services> { } 
}

This will extend the Vue prototype typings with

This file is picked up by typescript by declaring it in the "typeRoots" in the tsconfig.json.

{
  "compilerOptions": {
    "typeRoots": [
      "./node_modules/@types/",
      "./client/@types/"
    ],
  }
}

where store/index.ts contains this (and more). You should probably break this into it's own file actually, but I have it in store/index.ts along with my store content. Also this is importing the user service from my feathers server, which was generated by feathers-plus cli. It could simply be an interface that you define though.

import { User } from "../../server/services/v1/users/users.interface";
export interface Services {
  users: User;
}

Thanks for the clarification. Will try it as soon as I try another project with TypeScript and feathers-vuex!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

litti picture litti  Â·  3Comments

rayfoss picture rayfoss  Â·  7Comments

tguelcan picture tguelcan  Â·  6Comments

ontoneio picture ontoneio  Â·  7Comments

juancampuzano picture juancampuzano  Â·  4Comments