Reputation: 2678
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'
Upvotes: 3
Views: 2116
Reputation: 4647
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;
}
Upvotes: 4