aaronpowell / db.js

db.js is a wrapper for IndexedDB to make it easier to work against
http://aaronpowell.github.com/db.js/
MIT License
818 stars 142 forks source link

Typescript Definitions #126

Open mikemorton opened 9 years ago

mikemorton commented 9 years ago

I was just curious if anyone has written Typescript definitions for db.js?

brettz9 commented 8 years ago

Are there any needs that would be met in using TypeScript which the recent shift to using ES6 would not allow?

aaronpowell commented 8 years ago

I've been looking into this, TS definitions would be really nifty so you get API compilation validation but there's a problem, db.js generates a bunch of properties that map to the object store names in your db so you can do db.person.query(...) rather than db.query('person', ...). I can't find any way which I could support these run-time generated properties on the type definition exposed in the definition file, basically saying "the object has these properties and anything else is of type Server".

So this leaves two options:

  1. No TS definition file
  2. Have a TS definition file but when using TS you can't use the object store shorthand properties

I'm assuming the latter is preferred @mikemorton?

mikemorton commented 8 years ago

The later would be preferred. I don't mean to demand that project maintainers implement this for me, I was just curious if anyone had taking a stab at it.

@brettz9 to answer your question, I feel the static typing added by Typescript gives it a number of benefits over ES6. I obviously don't expect you guys just to go and implement the whole thing in Typescript just for me though.

In my project these are the typings I've been working with... they are not complete but they've let me move forward:

declare module db {

  interface ServerMethods {
    add<T>(table:string, ...objs:T[]):Promise<T[]>;
    add<T>(table:string, objs:T[]):Promise<T[]>;
    update<T>(table:string, ...objs:T[]):Promise<T[]>;
    update<T>(table:string, obj:T):Promise<T[]>;
    get<T>(table:string, id:number):Promise<T>;
    remove(table:string, n:number):Promise<number>;
    clear(table:string):Promise<void>;
    query<T>(table:string, field?:string, value?:string):QueryResult<T>;
    close():void;
  }

  interface QueryResult<T> {
    filter(f:(obj:T) => boolean):QueryResult<T>;
    filter(field:string, val:any):QueryResult<T>;
    only(val:any):QueryResult<T>;
    bound():QueryResult<T>;
    execute():Promise<T[]>;
    modify(obj:any):QueryResult<T>;
    all():QueryResult<T>;
    desc():QueryResult<T>;
    distinct():QueryResult<T>;
    upperBound():QueryResult<T>;
    lowerBound():QueryResult<T>;
  }

  export interface Server extends ServerMethods{

  }

  interface SchemaFields {
    // TO DO!
  }

  interface OpenParameters {
    server: string;
    version: number;
    schema: SchemaFields;
  }

  export function open(params:OpenParameters):Promise<Server>;

}

declare module "db.js" {
    export = db;
}
mdsharpe commented 8 years ago

There has been an effort to produce typings in the following branch: https://github.com/EnableSoftware/DefinitelyTyped/tree/add-dbjs-typings Your feedback would be welcome.

mikemorton commented 8 years ago

That looks incredible! Have you made a PR for definitelytyped?

brettz9 commented 8 years ago

That does look good--I particularly like the use of more explicit function names...

aaronpowell commented 8 years ago

Looks good. I've been toying with the idea of switching to TypeScript rather than Babel (I don't believe there's any features that don't work across). This way it's something that can be bundled into the release package too.

Out of curiosity, how does the deprecation of tsd impact the types from DefinatelyTyped?

brettz9 commented 8 years ago

ES7 is supposed to support Typed Objects, and MDN mentions that there is supposedly already experimental support in Firefox Nightly, and there does seem to be a goal for this new standard to impact at least Class field types.

(I haven't looked into this at any depth, but there appears to be a good tutorial out there at https://github.com/nikomatsakis/typed-objects-explainer and even a polyfill though not sure the latter would help in this case.)

As a possible middle-of-the-road solution between TypeScript and waiting until ES7, rtype sounds like an interesting approach (rfx also looks interesting).

My personal feeling is that using a comment-based approach for now may be more ideal:

  1. While TypeScript is well recognized, is a strict superset, does compile to JS, and might even conceivably compile to any standard that replaces its functionality, it is non-standard and, unlike using structured comments, using TypeScript requires JS developers to learn a new syntax to understand the code. It may not be that difficult, but my personal preference is really for standard or draft standard solutions or unobtrusive, progressive enhancements.
  2. While it can be an advantage, strong typing can also add a burden toward reading, debugging, and maintaining code as good clear variable names are lost amidst the sea of type information. To me, it's like good design; more is not always better, even though I agree that having the typed information in comments which can optionally be compiled into code which does do type checking, is a useful feature to have.

Just my 2 cents...