-
-
Save jack-guy/9d4ed79118e2656f5e3d2d699296ed36 to your computer and use it in GitHub Desktop.
| // Type definitions for Feathers | |
| // Project: http://feathersjs.com/ | |
| // Definitions by: Jack Guy <http://thatguyjackguy.com> | |
| // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped | |
| import { Application, Handler, ErrorRequestHandler } from 'express'; | |
| type HandlerArgument = Handler | Handler[]; | |
| export = Feathers; | |
| declare function Feathers(): Feathers.FeathersApp; | |
| declare namespace Feathers { | |
| // The app object returned from the feathers() constructor. Based on an Express app. | |
| export interface FeathersApp extends Application { | |
| // The version of Feathers from package.json | |
| version: string; | |
| methods: ['find', 'get', 'create', 'update', 'patch', 'remove']; | |
| services: any; | |
| providers: any[]; | |
| // Since configure was removed from Express | |
| configure(Function): this; | |
| service(location: string): service.FeathersServiceInstance<any>; | |
| // Mixture of Express and Feathers - we have to duplicate these because there's no way | |
| // in TypeScript to "override" an extends. So we rewrite them all, express included. | |
| use(location: string, service: service.FeathersServiceConfig): this; // Feathers | |
| use(...handlers: HandlerArgument[]): this; // Express | |
| use(mountPoint: string | RegExp | (string | RegExp)[], ...handlers: HandlerArgument[]): this; // Express | |
| use(errorHandler: ErrorRequestHandler); | |
| setup(app: FeathersApp); | |
| } | |
| // Expose these to users for typings their hook creations | |
| export type Hooks = hooks.FeathersHooks; | |
| export type Hook<Resource> = hooks.FeathersHook<Resource>; | |
| } | |
| // Contains the typings for service-related features | |
| declare namespace service { | |
| // The Events that can be subscribed to | |
| type FeathersEvent = 'create' | 'update' | 'patch' | 'remove'; | |
| // Shared methods between a FeathersService and it's instance | |
| interface FeathersServiceMethods<Resource> { | |
| find?(params: FeathersParams, callback?: Function): PromiseLike<FeathersPage<Resource>>; | |
| get?(id: any, params: FeathersParams, callback?: Function): PromiseLike<Resource>; | |
| create?(data: Resource, params: FeathersParams, callback?: Function): PromiseLike<Resource>; | |
| update?(id: any, data: Resource, params: FeathersParams, callback?: Function): PromiseLike<Resource>; | |
| patch?(id: any, data: Resource, params: FeathersParams, callback?: Function): PromiseLike<Resource>; | |
| remove?(id: any, params: FeathersParams, callback?: Function): PromiseLike<Resource>; | |
| } | |
| // The returned / retrievable feathers.service (e.g. app.service('/users')) | |
| interface FeathersServiceInstance<Resource> extends FeathersServiceMethods<Resource> { | |
| before(hooks: hooks.FeathersHooks); | |
| after(hooks: hooks.FeathersHooks); | |
| on(event: FeathersEvent, callback: { (Resource): any }); | |
| } | |
| // The interface that a new service object would implement | |
| interface FeathersService<Resource> extends FeathersServiceMethods<Resource> { | |
| (FeathersServiceConfig): FeathersServiceInstance<Resource>; | |
| setup?(app: Feathers.FeathersApp, path?: string) | |
| } | |
| // Change pagination for a 'find' service call | |
| interface FeathersFindConfig { | |
| paginate?: { | |
| default?: number; | |
| max?: number; | |
| } | boolean; | |
| } | |
| // Customize the creation of a feathers service | |
| interface FeathersServiceConfig extends FeathersFindConfig { | |
| before?: hooks.FeathersHooks; | |
| after?: hooks.FeathersHooks; | |
| } | |
| // The parameters used by feathers services | |
| interface FeathersParams { | |
| query: any; | |
| data: any; | |
| result: any; | |
| } | |
| // Paginated resources returned by find | |
| interface FeathersPage<Resource> { | |
| total: number; | |
| limit: number; | |
| skip: number; | |
| data: Resource[]; | |
| } | |
| } | |
| // Contains the typings for hook-related features | |
| declare namespace hooks { | |
| // The typings for the "hook" parameter in hook functions | |
| interface FeathersHookInputBase { | |
| method: string; | |
| type: 'before' | 'after'; | |
| callback: Function; | |
| params: any; | |
| data: any; | |
| app: Feathers.FeathersApp; | |
| } | |
| // We have an individual parameter typing for each hook type | |
| interface FeathersHookInputGet extends FeathersHookInputBase { id: any; } | |
| interface FeathersHookInputFind extends FeathersHookInputBase { } | |
| interface FeathersHookInputCreate extends FeathersHookInputBase { data: any; } | |
| interface FeathersHookInputUpdate extends FeathersHookInputBase { data: any; id: any; } | |
| interface FeathersHookInputPatch extends FeathersHookInputBase { data: any; id: any; } | |
| interface FeathersHookInputRemove extends FeathersHookInputBase { data: any; id: any; } | |
| type FeathersHookInputAll = | |
| FeathersHookInputGet | FeathersHookInputFind | FeathersHookInputCreate | | |
| FeathersHookInputUpdate | FeathersHookInputPatch | FeathersHookInputRemove; | |
| // The type of an actual hook function | |
| interface FeathersHook<Input> { | |
| (hook: Input): PromiseLike<any> | void | |
| } | |
| // Either an array of hooks or a single hook - | |
| // so we don't have to rewrite a super complicated type each time | |
| type FeatherHookArrayOrHook<Input> = Array<FeathersHook<Input>> | FeathersHook<Input>; | |
| interface FeathersHooks { | |
| all?: FeatherHookArrayOrHook<FeathersHookInputAll>; | |
| find?: FeatherHookArrayOrHook<FeathersHookInputFind>; | |
| get?: FeatherHookArrayOrHook<FeathersHookInputGet>; | |
| create?: FeatherHookArrayOrHook<FeathersHookInputCreate>; | |
| update?: FeatherHookArrayOrHook<FeathersHookInputUpdate>; | |
| patch?: FeatherHookArrayOrHook<FeathersHookInputPatch>; | |
| remove?: FeatherHookArrayOrHook<FeathersHookInputRemove>; | |
| } | |
| } |
Great work!
Don't you have to wrap this in declare module "feathers" { ...}? I couldn't get this file to work as is. Had to tinker with it a bit to get completion and everything compiling. My final results are here.
Something to keep in mind too:
I'm guessing feathers was compiled by Babel? There's a known issue with using export default that causes feathers.default (in the compiled js) to be undefined. That means you have to use export = Feathers which then requires an import via import feathers = require('feathers'); or import * as feathers from feathers. That one took me a while to figure out.
Does anyone have an example on how this type definition can be used? I am trying to implement it and finding it to be somewhat difficult
@Chrisdf I copy it into an index.d.ts file in a custom_typings folder and then npm link it into @types/feathers. Works like a charm. :)
Thank you!