Skip to content
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

Preparing a set of independent typings #19

Closed
phreed opened this issue May 13, 2016 · 8 comments
Closed

Preparing a set of independent typings #19

phreed opened this issue May 13, 2016 · 8 comments

Comments

@phreed
Copy link

phreed commented May 13, 2016

I have a framework library written in javascript.
https://github.com/webgme/webgme
The documentation looks reasonable.
https://editor.webgme.org/docs/source/PluginBase.html

As a first step in prepaing to use typing, I made a typing project and filled in a few interfaces by hand.
https://github.com/phreed/npm-webgme
I have a project that uses the webgme library.
https://github.com/phreed/webgme-immortals
That is being converted to use TypeScript.

Include the typing descriptions that are in phreed/npm-webgme into phreed/webgme-immortals.

typings install webgme=github:phreed/npm-webgm

How do I configure a project including the type definitions, to be used by a typescript project?

@blakeembrey
Copy link
Member

I'm sorry, I'm not sure what the question is. What incompatibilities have you run into?

@demurgos
Copy link

demurgos commented May 13, 2016

I think that you should install the npm-webgme directly from the github repo:

typings install -S github:phreed/npm-webgme#5a79adcf0051c6fc8b0b0500c4f7dcd56fdebdd4

This will install the definitions in typings/main/npm-webgme.

@blakeembrey I think he's just looking for the command to install the definitions (maybe we should an example of installation from github in the REAMDE.md of typings ?)

@phreed
Copy link
Author

phreed commented May 13, 2016

I am working through the process of preparing a set of typings independent of the source javascript.
I made this post in the hope that it will be useful to those who come after me.
Each of the steps in the original post was not immediately obvious.
The blocking issue when this post was first made was resolved by @demurgos comment.
Thanks

@phreed
Copy link
Author

phreed commented May 13, 2016

The next puzzle is how to get the imports to align with the definitions and source.

The JavaScript for which the TypeScript descriptions are being created.

  /**
     * Serializes this object to a JSON representation.
     *
     * @returns {object}
     */
    PluginConfig.prototype.serialize = function () {
        var keys = Object.keys(this);
...

https://github.com/webgme/webgme/blob/master/src/plugin/PluginConfig.js

A candidate import for the library

import PluginConfig = require("plugin/PluginConfig");

https://github.com/phreed/webgme-immortals/blob/typescript/src/plugins/push/push.ts

The attempt to describe the class

declare module plugin {

  interface PluginConfig {
    serialize(): any;
  }

  interface PluginBase {
    activeNode: any;
    activeSelection: any[];
    blobClient: any;
...

https://github.com/phreed/npm-webgme/blob/master/index.d.ts

These are inconsistent.
What would you recommend to make them play nice together?

@demurgos
Copy link

demurgos commented May 13, 2016

I am working through the process of preparing a set of typings independent of the source javascript.
Just to be clear, you have a JS package webgme and you write typings definitions in npm-webgame for it, to consume it in the TS package webgme-immortals ?

I'll just start with a little advice if you use TS, you can use the ES6 syntax for your imports:

import * as PluginConfig from "plugin/PluginConfig";

And just another note: typings is about managing external modules. For a simple npm package, you should not be using the module keyword in your definitions (because it creates a global name and can lead to various conflicts). Replace your module keyword by namespace and use exports inside to declare the public interfaces to avoid this issue.

Now, back to your problem:
What sort of module resolution are you using for you TS compilation ? Looks like classic but I want to be sure.

Why isn't the import import * as webgme from "webgme" ? You are writing definitions for webgme but importing something else. It's a bit confusing.

Anyway, given your definition, you should be able to consume it as:

import * as webgme from "webgme";

webgme.addCommitToResult("status"); // this is now type-checked
// ...

@phreed
Copy link
Author

phreed commented May 16, 2016

Just to be clear, you have a JS package webgme
https://github.com/webgme/webgme/blob/master/src/plugin/PluginConfig.js
and you write typings definitions in npm-webgame
https://github.com/phreed/npm-webgme/blob/master/index.d.ts
for it, to consume it in the TS package webgme-immortals ?
https://github.com/phreed/webgme-immortals/blob/typescript/src/plugins/push/push.ts

Correct.
The webgme/webgme JavaScript package is given (it would be difficult for me to get it changed).
The other two are under my control.
An earlier version of phreed/webgme-immortals (JavaScript with requirejs modules) worked correctly with webgme/webgme.
I will need to make many improvements to phreed/webgme-immortals and would like to have the TypeScript goodness.

I have not found a simple description of how the import, usage and type-description work together.

Here is an example (some repetition from the post above).
My attempts to construct type-descriptions for the existing webgme/webgme have not been successful.
One simple example for a constructor and a method call would probably do it.

A JavaScript 'plugin/PluginConfig.js' for which the TypeScript descriptions are being created.

Here is one plugin module, there are others.

 define([], function () {
    'use strict';
    var PluginConfig = function (config) {
        if (config) {
            var keys = Object.keys(config);
            for (var i = 0; i < keys.length; i += 1) {
                this[keys[i]] = config[keys[i]];
            }
        }
    };
    PluginConfig.prototype.serialize = function () {
        var keys = Object.keys(this);
        var result = {};
        for (var i = 0; i < keys.length; i += 1) {
            result[keys[i]] = this[keys[i]];
        }
        return result;
    };
    return PluginConfig;
});

https://github.com/webgme/webgme/blob/master/src/plugin/PluginConfig.js

A candidate import from the library.

This is apparently wrong but I do not know why.

import PluginConfig = require("plugin/PluginConfig");
let pb = new PluginConfig(config);

https://github.com/phreed/webgme-immortals/blob/typescript/src/plugins/push/push.ts
I do not understand how the sample...

import * as webgme from "webgme";
webgme.addCommitToResult("status");

...would even work as 'webgme' is a module/namespace and 'addCommitToResult("status")'
is a method from an interface.

An attempt to describe the class

I am pretty sure my type description is wrong.
https://github.com/phreed/npm-webgme/blob/master/index.d.ts
What would a good approach look like and why?

Is there a good example of a similar project that I could look at?
Maybe https://github.com/typed-typings/npm-debug ?
or https://github.com/facebook/immutable-js + https://github.com/typed-typings/npm-immutable
typed-typings/npm-debug does not have any tests which show how to use the library.

@unional
Copy link
Member

unional commented May 27, 2016

I'll just start with a little advice if you use TS, you can use the ES6 syntax for your imports:

Actually, don't do that. The interop capability would cost you. I used to also advice the same, but now I have changed my mind. See:
https://github.com/unional/typescript/blob/master/style-guide/default/modules.md#import-keyword

@phreed
Copy link
Author

phreed commented Jun 23, 2016

#25 resolved the issues.

@phreed phreed closed this as completed Jun 23, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants