7

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

    Brandon
    • 984
    • 1
    • 11
    • 26
    • As long as you are using visual studio 2013 and the d.ts is in the same project as your .ts file you don't need to include anything in the file itself. Make sure they are in the same module though first as a test to make sure it works – John Nov 21 '14 at 18:45
    • Thanks, I have the web application project's Module System set for AMD. The enum file and definition file are in different folders. The defintion file is currently being used as a common point to hold references used by files throughout the project. I didn't think the module names would matter using AMD? – Brandon Nov 21 '14 at 18:55
    • I haven't used AMD for a long time so don't remember how it imports these days so not sure. I do know that with VS you don't need to include the `/// references` anymore which is nice. I would try using the same module for both to get it to work and then worry about getting it working with AMD – John Nov 21 '14 at 19:25

    2 Answers2

    4

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

    There are workaround as Steve Fenton pointed out, but the system isn't designed for this. You should reference other definition files in your definition file and not reference an *implementation file * (MyEnum.ts) in a definition file.

    basarat
    • 261,912
    • 58
    • 460
    • 511
    • 3
      I'm leaning towards this, makes sense the definition shouldn't refer to an implementation. I thought about it and realized I was focused on "how" instead of "should I". A co-worker made the d.ts file, and I wasn't questioning the validity at first, but I just turned it into a .ts (I get the feeling d.ts is mainly for providing typing to existing js?) and it worked fine. I'm still confused as to how a type file would designate an enum type? – Brandon Nov 26 '14 at 20:40
    2

    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.

    Fenton
    • 241,084
    • 71
    • 387
    • 401
    • 1
      I tried this, but it caused the code file to not be able to find the definitions (it's like the import causes some issue). I guess basarat is right, but you pointed in that direction as well. – Brandon Nov 26 '14 at 20:44
    • I have updated my answer regarding the suggestion you can't mix implementation and declaration code as I couldn't fit it in a comment :) – Fenton Nov 26 '14 at 21:00
    • 1
      Thanks, that is good info. I updated my OP with some additional detail. – Brandon Nov 28 '14 at 14:55
    • Two changes to fix that... 1. in MyDefinitions `export = MyDefinitions;` and 2. in MyClass `import MyDefinitions = require('MyDefinitions');`. – Fenton Nov 28 '14 at 15:30
    • 1
      Missed that, thanks! Had to use import MyDefinitions = require('../Definitions/MyDefinitions');, but it worked fine after that. I've been mostly C# for the last 10 years, guess typescript is rattling my brain :) – Brandon Nov 28 '14 at 16:18