ArnoSaine / react-pouchdb

React wrapper for PouchDB that also subscribes to changes.
ISC License
125 stars 9 forks source link

TypeScript definitions #15

Open digizen opened 4 years ago

digizen commented 4 years ago

Has anyone thought about adding TypeScript type definitions for this project? I find types are hugely helpful for me when I'm using various libraries.

I ran the library through the Microsoft Types generator (dts-gen) and it came up with this starter file. Obviously it needs a bunch of work to make it useful.

 /** Declaration file generated by dts-gen */

export const DBContext: {
    Consumer: {
        $$typeof: any;
        Consumer: any;
        Provider: {
            $$typeof: any;
        };
    };
    Provider: {
        $$typeof: any;
    };
    default: {
        $$typeof: any;
        Consumer: {
            $$typeof: any;
            Consumer: any;
            Provider: {
                $$typeof: any;
            };
        };
        Provider: {
            $$typeof: any;
        };
    };
};

export function Find(_ref: any): any;

export function Get(_ref: any): any;

export function PouchDB(_ref: any): any;

export function useDB(any: any, ...args: any[]): any;

export function useFind(...args: any[]): any;

export function useGet(...args: any[]): any;

export function withDB(...args: any[]): any;
ArnoSaine commented 4 years ago

This hasn't come up previously. If you want to look into it more, please do. It would be great if @types/pouchdb could also be leveraged, because some params go as is to PouchDB.

jemc commented 3 years ago

I ran across this today and wrote up types for all the public API calls documented in the README, leveraging the PouchDB types as a basis. I'm not skilled enough with package.json magic to figure out how to make sure they get published in the package, so I can't do a proper pull request to get it all done, but I can paste my type definitions here for anyone who wants to use them as-is in their own project, or carry it along the last mile to getting them into this repo:

/// <reference types='react' />
/// <reference types='pouchdb' />
/// <reference types='pouchdb-core' />
/// <reference types='pouchdb-find' />

declare module "react-pouchdb/concurrent" {
  interface PouchDBProps extends PouchDB.Configuration.DatabaseConfiguration {
    name: string
    maxListeners?: number
    children?: ReactNode
  }
  export function PouchDB(props: PouchDBProps): JSX.Element

  export function useDB(db?: string | PouchDBProps): PouchDB.Database

  ///
  // useGet and Get

  interface GetOptions extends PouchDB.Core.GetOptions {
    attachments?: boolean | string
  }
  type GetResult<Model> =
    | (PouchDB.Core.Document<Model> & PouchDB.Core.GetMeta)
    | undefined
    | null

  export function useGet<Model>(options: GetOptions): GetResult<Model>
  export function useGet<Model>(
    db?: string | PouchDBProps,
    options: GetOptions
  ): GetResult<Model>

  interface GetProps extends GetOptions {
    db?: string | PouchDBProps
    children: (props: {
      db: PouchDB.Database
      doc: GetResult<Model>
    }) => JSX.Element
  }
  export function Get(props: GetProps): JSX.Element

  ///
  // useFind and Find

  type FindOptions = PouchDB.Find.FindRequest
  type FindResult<Model> = PouchDB.Core.ExistingDocument<Model>[] | undefined

  export function useFind<Model>(options: FindOptions): FindResult<Model>
  export function useFind<Model>(
    db?: string | PouchDBProps,
    options: FindOptions
  ): FindResult<Model>

  interface FindProps extends FindOptions {
    db?: string | PouchDBProps
    children: (props: {
      db: PouchDB.Database
      docs: FindResult<Model>
    }) => JSX.Element
  }
  export function Find(props: FindProps): JSX.Element

  ///
  // useAllDocs and AllDocs

  type AllDocsOptions =
    | PouchDB.Core.AllDocsWithKeyOptions
    | PouchDB.Core.AllDocsWithKeysOptions
    | PouchDB.Core.AllDocsWithinRangeOptions
    | PouchDB.Core.AllDocsOptions
  type AllDocsResult<Model> =
    | {
        doc?: PouchDB.Core.ExistingDocument<Model & PouchDB.Core.AllDocsMeta>
        id: PouchDB.Core.DocumentId
        key: PouchDB.Core.DocumentKey
        value: {
          rev: PouchDB.Core.RevisionId
          deleted?: boolean
        }
      }[]
    | undefined

  export function useAllDocs<Model>(
    options: AllDocsOptions
  ): AllDocsResult<Model>
  export function useAllDocs<Model>(
    db?: string | PouchDBProps,
    options: AllDocsOptions
  ): AllDocsResult<Model>

  interface AllDocsProps extends AllDocsOptions {
    db?: string | PouchDBProps
    children: (props: {
      db: PouchDB.Database
      rows: AllDocsResult<Model>
    }) => JSX.Element
  }
  export function AllDocs(props: AllDocsProps): JSX.Element
}
ArnoSaine commented 3 years ago

Thanks @jemc! I'll add these to the package.

jemc commented 3 years ago

@ArnoSaine - quick note, in case you're not aware of this part: the declare module part is only needed in my snippet above because I'm declaring types for a different module from my project that uses that module.

Since you're adding them to the module proper, I think the declare module encompassing scope can be removed, and they're just supposed to go in a file named index.d.ts within the module.

elijahdorman commented 3 years ago

@jemc

I'm hardly a TS or PouchDB expert, so maybe I messed something up, but the PouchDBProps definition isn't actually accepting the other configuration props. Manually copying in from the other type definition gets it working again.