Skip to content

TypeScript Definition Done! #167

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
TeamworkGuy2 opened this issue Jun 11, 2015 · 19 comments
Closed

TypeScript Definition Done! #167

TeamworkGuy2 opened this issue Jun 11, 2015 · 19 comments
Labels

Comments

@TeamworkGuy2
Copy link
Contributor

Wasn't sure where to post this, it's not an issue, just wanted to let those who use LokiJS know.

For those of you who use or might be interested in TypeScript, there's a newly added TypeScript definition for LokiJS over at the DefinitelyTyped repository: https://github.com/borisyankov/DefinitelyTyped/tree/master/lokijs.

@techfort
Copy link
Owner

Excellent! Thank you! Will include this in the docs on the website.

@obeliskos
Copy link
Collaborator

Yea thanks! I wonder if this could be used in an editor like Visual Studio Code to get intellisense.

@obeliskos
Copy link
Collaborator

We may need to revisit this in the future as our api surface evolves, but this seems a closed issue, thanks!

@TeamworkGuy2
Copy link
Contributor Author

Moved to new issue #268

I was thinking about that recently, I was wondering if you guys would be interested in upgrading Loki to typescript and pros/cons from your viewpoint?

My viewpoint after writing the definition file for LokiJS is that there's no obvious downsides to TypeScript for an OOP JS library like LokiJS, the code doesn't doing anything crazy with prototypes or function argument and makes an excellent target for TypeScript.
Since typescript is just javascript with types and there's a dozen tools and IDEs to compile .ts to .js when you save a file or as part of the build process, keeping side-by-side .ts and .js files in the '/src' directory wouldn't take much effort, thoughts?

(based on my experience over the last 6 months working on a large business web app using VS2015 + TypeScript + LokiJS + lokijs.d.ts file linked in the OP)

@OzzieOrca
Copy link

How should I go about importing and using Loki with the LokiIndexedAdapter in Typescript using this definition?

I've imported Loki using:

import * as Loki from 'lokijs';

//Usage
var db = new Loki('my-app', {});

which compiles but is looking for the module fs which isn't available in the browser.

I'd like to be able to do something like:

import {Loki, LokiIndexedAdapter} from 'lokijs';

export class LokiJSService {
  constructor() {
    var iDBAdapter = new LokiIndexedAdapter('my-app-db');
    var db = new Loki('my-app',
      {
        adapter: iDBAdapter
      }
    );
  }
}

but can't seem to get the imports/exports right. I tried modifying the type definition file too. I'm new at using TypeScript and I know I haven't changed some of the code to use TypeScript features or the class fully. I'm just trying to get the imports to work first. If there are any docs you guys could point me to that would be helpful too. Thanks!

@obeliskos
Copy link
Collaborator

I have not yet had the time to experiment that much with typescript or the definitions which @TeamworkGuy2 created for us, so I unfortunately can't provide any immediate help on this issue.

The typescript definitions appear 9 months old so it is quite possible they are outdated. I would like at some point in the future to revisit this but have not had time.

I'm not certain if he wants dissemination of this (and I just found so i'm not sure if its ready), but it would appear @TeamworkGuy2 is actively working on typescript wrapper for loki collections here :

https://github.com/TeamworkGuy2/lokijs-collections

(TWG2 if you would prefer I not link to that project, let me know and I will remove.)

If anything it may give you some ideas while you are learning typescript with loki.

@TeamworkGuy2
Copy link
Contributor Author

I'm happy to have you link to it! Yes, the definition is somewhat out of date and I haven't had the interest in updating it since I've been working on the lokijs-collections project you linked to.

Lokijs-collections is a work in progress, it's designed around meta-data schemas for each collection. These schemas containing primary key column names, non-nullable column names, data types, and a few other optional pieces that are used by new functions like DataCollection.addOrUpdate(). We use this meta-data to add constraints (such as uniqueness and auto-generated columns) to lokijs-collections without adding any additional API complexity to the developer besides setting up the initial schemas.

The purpose of the library may not match your needs @OzzieOrca, but it does have some unit tests which contain code that uses the loki TypeScript definition file. You might be able to use it as a guide for using the typescript definition file in your project.

You are right, Lokijs does require('fs') for the optional LokiFsAdapter (https://github.com/techfort/LokiJS/blob/master/src/lokijs.js#L1068).
If you're running in the browser, I'd comment out or remove lines 1058 (https://github.com/techfort/LokiJS/blob/master/src/lokijs.js#L1058) through 1112 (https://github.com/techfort/LokiJS/blob/master/src/lokijs.js#L1112) and any other references to LokiFsAdapter. That should fix the missing 'fs' issue you mentioned.

@TeamworkGuy2
Copy link
Contributor Author

Fyi, @obeliskos and @OzzieOrca, I updated lokijs.d.ts type definition over on DefinitelyTyped to latest loki.js v1.3.16.

@obeliskos
Copy link
Collaborator

That's awesome, thank you! Interesting project as well :)

@thasmo
Copy link

thasmo commented Nov 24, 2017

Typings are located here, although they don't seem to be up-to-date.

Type definitions for lokijs v1.2.5

@nmocruz
Copy link

nmocruz commented Nov 27, 2017

@thasmo is not updated and is missing a few thing there. I don't see updateWhere and there's conflicts and a few methods

@TeamworkGuy2
Copy link
Contributor Author

@thasmo, @nmocruz - [email protected] definition just got merged to definitely typed (pull: DefinitelyTyped/DefinitelyTyped#21747, commit: DefinitelyTyped/DefinitelyTyped@766089f). Should auto update to npm in a day or two.
Took me ~10 hrs, documentation from lokijs source included, hope it works well for those of you using it.

@thasmo
Copy link

thasmo commented Dec 2, 2017

@TeamworkGuy2 Thanks for your work on this, spending so much time! I'll definitely have a look.

@Viatorus
Copy link
Collaborator

Viatorus commented Dec 4, 2017

@TeamworkGuy2 Very good work!

Just one question: Does the LokiQuery works with nested properties?

@TeamworkGuy2
Copy link
Contributor Author

TeamworkGuy2 commented Dec 5, 2017

@Viatorus No, although I left LokiQuery<E> as a global interface type so you can extend it in your own code to add functionality.

EDIT:
The ability to handling nested properties is an interesting challenge which I didn't fully explorer while initially creating the lokijs definition.
So I experimented a little this evening, the problem is:

  1. LokiOps has a lot of properties, for example $contains, which we leave as type any because they can be nested. Now it's possible to create nested types (see point 2), but if we did, it would lead to un-intelligiblely long error messages which would leave most TypeScript coders confused when compiling incorrect queries and impossible to read hover-over hints in IDEs. So I don't attempt to mimic nested queries and just use any.

  2. It's not practical using TypeScript's current type system to create types that try to use nested properties because the TS type system doesn't provide a way of filtering out primitives like number, string, and boolean, as well as core types like RegExp and Date (atleast there's no type filtering syntax I'm aware of as of TypeScript 2.6), so recursive types end up looking ridiculous:

Let's create a tripled nested version of LokiQuery:

type PartialModelNested<E, T> = { [P in keyof E]?:
  { [P2 in keyof E[P]]?:
    { [P3 in keyof E[P][P2]]?: any }
  } | T
};
type LokiQuery<E> = PartialModelNested<E & { $and: any; $or: any }, { [Y in keyof LokiOps]?: any }>;

var query: LokiQuery<{ name: string; posts: { id: number; text: string }[] }> = {
  name: "abc",
  posts: { ...
};

The problem quickly becomes apparent when we try to write a query using our new type.
Let's say I stop typing inside posts: { ... and check for auto-completion help. In Visual Studio, the hover-over takes about two seconds to looks strange, see image below.
You can see how we're recursively digging through every enumerable string properties (codePointAt, includes, endsWith, etc) on just the first name: string property of our model!
This type definition is probably hundreds if not thousands of lines long!
So we compromise and mimic the first layer of a valid Lokijs query object in our LokiQuery interface to save us from this mess.
image

@Viatorus Viatorus reopened this Dec 5, 2017
@nmocruz
Copy link

nmocruz commented Dec 5, 2017 via email

@Viatorus
Copy link
Collaborator

Viatorus commented Dec 5, 2017

@TeamworkGuy2 thank you for your explanation.

What you wanted can maybe implement this way:

type R<T> = {
    [P in keyof T]: R<T[P]>;
}

interface Foo {
    bar: {
        baz: {
            name: string;
        }
    }; 
}

let r: R<Foo>;
r.bar.baz.name = "123";

But this does not help here.
The real obstacle is: LokiJS (and MongoDB) accesses nested properties using the dot syntax:

let query = {"bar.baz.name": 123}

Currently, typescript cannot handle this in an easy way. (There are some proposals like this one).

What I have done today is the following:

/**
 * E = the data type
 * N = the nested properties
 */
class Collection<E, N> {
    public data(): E[];

    public find(LokiQuery<E & N>); 
}

interface Foo {
    bar: {
        baz: {
            name: string;
        }
    }; 
}

let coll = new Collection<Foo, {"bar.baz.name": string}>
coll.find({"bar.baz.name": "test"});

@TeamworkGuy2
Copy link
Contributor Author

@Viatorus good stuff, thanks for sharing! That's why I made all the interfaces global so other people can extend them to work best in their own situations.

@stale
Copy link

stale bot commented Jul 13, 2018

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Jul 13, 2018
@stale stale bot closed this as completed Jul 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants