Search code examples
dojotypescriptamd

Why (in typescript 0.9.5) do I now get a bunch of "invalid new expression" errors? Example:


Typescript 0.9.5 I now catching errors which were not reported in 0.9.1. From dojo.d.ts:

declare module Dojo {
    class Color {
        constructor();
        constructor(colors: any[]);
    }
}

usage:

var Color: Dojo.Color;
new Color([1,2,3]);

The error:

Invalid 'new' expression.

This error makes sense. The solution seems to be to change the class to an interface. This works:

declare module Dojo {
    interface Color {
        new();
        new(colors: any[]);
    }
}

var Color: Dojo.Color;
new Color([1, 2, 3]);

So my actual question is this...what is a good pattern to follow for AMD style typescript coding? Here is what I have come up with to handle this particular example:

declare module Dojo {
    class Color {
    }

    interface IColor {
        new(): Color;
        new (colors: any[]): Color;
    }
}

Usage:

require(["dojo/_base/Color", function (Color: Dojo.IColor) {    
    new Color([1, 2, 3]);
}

Or maybe there's a way to use the existing definition in dojo.d.ts?


Solution

  • TypeScript is even friendlier for working with AMD than you think. Assuming you're working with the d.ts file available here, this is what your code should look like:

    /// <reference path="./dojo.d.ts"/>
    
    import Color = require("dojo/_base/Color");
    var c = new Color([1, 2, 3]);
    

    and this is what that compiles to:

    define(["require", "exports", "dojo/_base/Color"], function(require, exports, Color) {
        var c = new Color([1, 2, 3]);
    });
    

    You can use multiple import statements in your code and the compiler will organize them for you.

    You'll need to tell the compiler that it's the AMD module system you're using (and not commonjs) with the -m AMD command line switch or the <TypeScriptModuleKind>amd</TypeScriptModuleKind> property in your Visual Studio csproj.


    Edit: Alternately you can use the typeof type operator to refer to the shape of a module.

    /// <reference path="./dojo.d.ts"/>
    
    declare function require(name: string): any;
    
    var Color: typeof Dojo.Color = require("dojo/_base/Color");
    var c = new Color([1, 2, 3]);
    

    This doesn't provide as much type safety as the above solution.