Search code examples
visual-studio-2013enumsrequirejstypescriptamd

How do I reference a Typescript enum inside a definition file


I am using Visual Studio 2013 with update 4 and Typescript 1.3 installed.

If I have a typescript file, like so:

MyEnums.ts:

export = MyEnumModule;
module MyEnumModule {
    export enum AnEnum { RED, BLUE, GREEN }
}

And I have a definitions file like so:

MyDefinitions.d.ts:

declare module MyDefinitions {
    interface ISomeInterface {
        aProperty: string;
        aMethod: () => void;
        aColor: MyEnumModule.AnEnum;
    }
}

I basically get an error of "Cannot find name 'MyEnumModule'"

This enum file works fine when referenced from typescript files. For instance:

SomeCode.ts:

export = MyCode;

import MyEnums = require('MyEnums');

module MyCode{

    export class MyClass implements ISomeInterface {
        public aColor: MyEnums.AnEnum = MyEnums.AnEnum.RED;
        ...and so on

My understanding is that adding either /// <reference ... or an import will not work for a .d.ts file (I tried just to be sure and it didn't appear to work either way).

Does anyone know how to reference an enum in a definition file like this?

Thanks in advance.

--Update:

Here is the error I see after trying Steve Fenton recommendations below (with a sample project I just made).

MyDefinitions.ts:

import MyEnumModule = require('../App/MyEnums');

declare module MyDefinitions {
    interface ISomeInterface {
        aProperty: string;
        aMethod: () => void;
        aColor: MyEnumModule.AnEnum;
    }
}

MyEnums.ts:

export = MyEnumModule;

module MyEnumModule {
    export enum AnEnum { RED, BLUE, GREEN }
}

MyClass.ts:

export = MyCode;
import MyImport = require('MyEnums');
module MyCode {
    export class MyClass implements MyDefinitions.ISomeInterface {
        public aColor: MyImport.AnEnum = MyImport.AnEnum.RED;
        constructor() { }
        aProperty: string = "";
        aMethod: () => void = null;       
}

}

Folder structure:
App

  • -MyClass.ts
  • -MyEnums.ts

  • Defintions
  • -MyDefintions.d.ts
  • Inside MyClass.ts MyDefinitions.ISomeInterface is underlined in red with hover warning "Cannot find name MyDefinitions".

    I have AMD set for the project


    Solution

  • I had a check on this and the following definition works for me, although I must admit I have never referenced "actual" code from "definition" code - but I can't think of any reason not to.

    import MyEnumModule = require('MyEnumModule');
    
    declare module MyDefinitions {
        interface ISomeInterface {
            aProperty: string;
            aMethod: () => void;
            aColor: MyEnumModule.AnEnum;
        }
    } 
    

    On mixing definitions and real implementations...

    The type system in TypeScript is a design time and compile-time tool. When the type information is constructed at design time it makes no difference whether the type information is inferred from implementation code, taken from annotations that decorate implementations or come from an ambient declaration.

    There are many use cases for mixing implementation code and ambient declarations - if you are migrating a million-line JavaScript program to TypeScript, you may not be able to migrate it from the bottom-most dependency upwards. Also, you can place ambient declarations inside of normal files - not just definition files - if you have a large program, you may not even know whether a type you place in an ambient declaration is "real" or "ambient".

    The only difference between implementation code types and ambient declaration types is that the type information is right next to the implementation in real code files, and in a separate file for ambient declarations.

    So... if you are having a problem using real implemented types in your ambient declaration, it is most likely caused by something that can be fixed. The example I supplied above works in a project I have in Visual Studio 2013, Update 4 - with TypeScript build configuration set to compile AMD modules. If you can share the exact details of the problem, I'm happy to help you get it working.

    Having said this - if you are creating a type definition for trivial amounts of code, pasting them into a .ts file may even be faster than writing the definition - so you should make a case-by-case decision on where to spend the effort.