Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

    like image 200
    Brandon Avatar asked Nov 21 '14 18:11

    Brandon


    People also ask

    Can I use TypeScript enum in JavaScript?

    Enums are a feature added to JavaScript in TypeScript which makes it easier to handle named sets of constants. By default an enum is number based, starting at zero, and each option is assigned an increment by one. This is useful when the value is not important.

    Can we define enum inside a class TypeScript?

    To use enums inside a class with TypeScript, we can put it in the same module as the class. to add the Image class that has the static State variable set to the State enum. Then we can use it with Image.

    Can I use enum as a type in TypeScript?

    In TypeScript, enums, or enumerated types, are data structures of constant length that hold a set of constant values. Each of these constant values is known as a member of the enum. Enums are useful when setting properties or values that can only be a certain number of possible values.

    What do TypeScript enums compile to?

    Enums in TypeScript isn't only a compile-time feature. The enum type does actually gets compiled into a JavaScript object. This program when compiled produces the following output.


    2 Answers

    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.

    like image 157
    basarat Avatar answered Sep 28 '22 10:09

    basarat


    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.

    like image 43
    Fenton Avatar answered Sep 28 '22 09:09

    Fenton