enums in definition file?

Topics: General
Sep 17, 2013 at 11:45 AM
Hi,
take a look at this simple example:
enum ProcessStatus {
    Starting,
    Started
}

interface IProcess {
    getStatus(): ProcessStatus;
}

class Process implements IProcess {
    getStatus(): ProcessStatus {
        return ProcessStatus.Started;
    }
}

var process = new Process();
console.log(ProcessStatus[process.getStatus()] + ":" + process.getStatus());
Now I would like to move enum and interface definition to .d.ts file, like this:

test.d.ts
declare enum ProcessStatus {
    Starting,
    Started
}

interface IProcess {
    getStatus(): ProcessStatus;
}
test.ts
/// <reference path="test.d.ts" />
enum ProcessStatus {
    Starting,
    Started
}

class Process implements IProcess {
    getStatus(): ProcessStatus {
        return ProcessStatus.Started;
    }
}

var process = new Process();
console.log(ProcessStatus[process.getStatus()] + ":" + process.getStatus());
but this doesn't compile. I have tried to change the code in different ways, but I was not able to make it compile and run as expected.... So how to correctly define enum in d.ts file?

thanks
Sep 17, 2013 at 3:21 PM
@EdvinV, I don't believe there is a simple solution for this. You may have to do the following:

You will need three compilation units.
  • Put your enum code into the first compilation unit. Do not create a declaration for the enum. Simply compile with the TypeScriptGeneratesDeclarations set to true.
  • Put your interface into the second. Add a reference to the generated enum.d.ts.
  • Put your class into the third compilation unit. Add a reference to interface.d.ts (there is no need to refence enum.d.ts).
There may be an easier way to do this - if so I'd be interested.

But the problem is one cannot declare as well as define a type within site of each other.
Sep 17, 2013 at 3:53 PM
I'm assuming here that you want to split your code into separate compilation units (i.e. projects in Visual Studio). If they are all in the same project then you can simply omit the declare enum and it should work.
Developer
Sep 18, 2013 at 11:03 PM
@EdvinV, remember that /// <reference /> is special in that it tells your tools that "Even though you currently don't see this code, treat it as if the browser/runtime environment already has it loaded." When you do that with a .d.ts file, it's still effectively the same idea - the type information provided by the .d.ts file is enough to provide the shape of the objects that are loaded in the runtime environment.

As a result, when you /// <reference path="test.d.ts" />, and then you include the enum in the referencing file, you're effectively redeclaring the enum, which is why the compiler is issuing the error.

What you can do is:
test.ts: Compile with -d
enum ProcessStatus {
    Starting,
    Started
}

interface IProcess {
    getStatus(): ProcessStatus;
}
user.ts:
/// <reference path="test.d.ts" />

class Process implements IProcess {
    getStatus(): ProcessStatus {
        return ProcessStatus.Started;
    }
}
When you're trying to use it in a browser, you need to ensure that you're referencing both files:
<script src="test.js"></script>
<script src="user.js"></script>
That should work for you.