3

I am just trying to mess around with PaperJS in TypeScript and I could not find a definition so I am creating my own one.

There is a situation that I have seen twice when dealing with definition files. In my case, there is a global variable called paper. But there also appears to be a module called paper too.

How does one deal with this without getting a duplicate identifier error?

Important Note! Perhaps paper does not have a module name.... Maybe every function is on the global scope. I do not really understand the architecture.

paper.d.ts

declare var paper: paper.PaperScope;

declare module paper{
    export class PaperScope{
       ....
    }
}

Duplicate Identifier 'paper'

1 Answer 1

4

In this case, I don't think you need to separately declare the paper variable and then declare the module - it works to just use declare module paper. There may be more to the library that will change the approach, but I was able to at least get the initial example working.

The recommended way to generate a TypeScript definitions file by hand is to copy and paste as many samples as you can find off the library's web site into separate functions in a new TypeScript file that have a link back to where you found them. Turn off "Allow implicit 'any' types" in the VS TypeScript Build window, or use the --noImplicitAny command line switch. Then reference your d.ts file at the top and start working each error one by one. Once your TypeScript file compiles without error, you can have fair confidence that it's correct at least as far as the tests you've assembled. (You don't actually have to "run" any tests - it's sufficient for the TypeScript file to compile without error since we're testing the definition, not the code.)

Note: it is common to have to make minor tweaks to the sample to cast things as needed. You can see that I casted canvas as an HTMLCanvasElement. I could have made the setup method in the declaration accept a regular HTMLElement instead. This would have required no casting from getElementById(), but it would also not nudge the user of the definition in the correct direction, so there can be some style decisions involved.

If you come up with a good definition for a library, please contribute it to the DefinitelyTyped library on GitHub. http://definitelytyped.org/guides/contributing.html

Here's what I was able to come up with to get you started using the strategy above:

paper-tests.ts

///<reference path="paper.d.ts" />
// tests for hypothetical paper.js definitions file.

/** Test from http://paperjs.org/tutorials/getting-started/using-javascript-directly/#making-the-scope-global */
function settingUpAScope() {
    // Get a reference to the canvas object
    var canvas = <HTMLCanvasElement>(document.getElementById('myCanvas'));
    // Create an empty project and a view for the canvas:
    paper.setup(canvas);
    // Create a Paper.js Path to draw a line into it:
    var path = new paper.Path();
    // Give the stroke a color
    path.strokeColor = 'black';
    var start = new paper.Point(100, 100);
    // Move to start and draw a line from there
    path.moveTo(start);
    // Note that the plus operator on Point objects does not work
    // in JavaScript. Instead, we need to call the add() function:
    path.lineTo(start.add([200, -50]));
    // Draw the view now:
    paper.view.draw();
}

paper.d.ts

declare module paper {

    export class Path {
        strokeColor: string;
        moveTo: (destination: Point) => void;
        lineTo: (destination: Point) => void;
    }
    export class Point {
        constructor(x: number, y: number);
        x: number;
        y: number;
        add: (something: number[]) => Point;
    }

    export interface IView {
        draw: () => void;
    }

    var view: IView;

    function setup(element: HTMLCanvasElement): void;
}
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks so much for your detailed response. I really appreciate it! I am familiar with DT but the problem is, I do not know what a "good" definition is yet :P. You use IView interface, whereas I would use export class View so I have to iron these out as to why I would use one over the other.
I am not familiar with paper.js, but based on the sample from their site, view is something that didn't have to have new called on it to use - it just existed automatically on paper. Due to this, I figured it was easier to declare whatever view was as an interface since interfaces are generally the most flexible building blocks in TypeScript declarations. If I had declared it as a class, that technically would have allowed someone to call var v = new paper.view(); If that is valid, then perhaps a class would be better; if it's not valid, then the interface is probably correct.
@Clark Did you get anywhere with this? I'd love it if you could share your definition if so - otherwise I'll have to write my own!
@Clark found it on your github. You have no idea how happy this makes me - thanks for your hard work!
It might need some work mate! It might be a couple of versions old but it was good enough at the time for what I needed.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.