René Sackers
René Sackers

Reputation: 2635

Typescript definition with custom const enum

I'm trying to create TypeScript definition files for a library.

The library has a method that accepts a parameter of type number, but that parameter can only be a certain set of numbers, so I want to have my definition say it requires an enum type that I created using a const enum.

However, when I define my class in a .d.ts, like so:

// definitions/SimpleDefinition.d.ts

/// <reference path="Enums.ts" />

declare class SampleDefinedClass {
    public static SampleMethod(enumArg: Enums.SampleEnum): void;
}

My enum like this:

// definitions/Enums.ts

export const enum SampleEnum {
    Item1 = 1,
    Item2 = 2
}

And I have an index.d.ts to tie the 2 together:

// definitions/index.d.ts

/// <reference path="Enums.ts" />
/// <reference path="SampleDefinition.d.ts" />

The compiler tells me this:

../definitions/SampleDefinition.d.ts(4,41): error TS2503: Cannot find namespace 'Enums'.

I have tried adding an import to the top of my SampleDefinition.d.ts, but that resulted in the definition not being properly recognized in my code file. Though Visual Studio and Visual Studio code won't show an error on the actual import.

import Enums = require("./Enums");

Main.ts(6,1): error TS2304: Cannot find name 'SampleDefinedClass'.

I have tried several more thing, like using AMD, and moving files around, but can't seem to get this to work. Is there a way to do this? Or will I have to find another way to do it/give up?

I've created a GitHub repo with this exact sample.

Upvotes: 3

Views: 1765

Answers (2)

artem
artem

Reputation: 51629

Your SampleDefinition.d.ts does not have top-level import or export, and Enum.ts does. That is, Enums is a module, while SampleDefinition is not, but you are trying to use Enums in it. Using older (outdated) terminology, SampleDefinition.d.ts is an internal module, and Enums is external module, and you can't mix the two in one application.

There are two ways to make them consistent:

One way is to make everything internal, without any import/export at top level:

fixed Enum.ts: wrap export in a namespace

namespace Enums {
    export const enum SampleEnum {
        Item1 = 1,
        Item2 = 2
    }
}

fixed Main.ts - just remove import Enums .. line

/// <reference path="../definitions/index.d.ts" />

console.log(Enums.SampleEnum.Item2);
SampleDefinedClass.SampleMethod(Enums.SampleEnum.Item1);

Another way is to turn everything into a module:

fixed SampleDefinition.ts : use import instead of reference, and export class instead of declaring it:

import Enums = require("./Enums");


export class SampleDefinedClass {
    public static SampleMethod(enumArg: Enums.SampleEnum): void;
}

fixed Main.ts: again, import everything explicitly instead of reference. That way, you don't need definitions/index.d.ts at all:

import Enums = require("../definitions/Enums");
import {SampleDefinedClass} from "../definitions/SampleDefinition"


console.log(Enums.SampleEnum.Item2);
SampleDefinedClass.SampleMethod(Enums.SampleEnum.Item1);

Which way to choose is up to you. The main difference is that with modules, your app will require module loader at runtime. Without modules, it can be compiled into one combined script file. This matters mostly for browsers (where you have to provide module loader yourself), modular code compiled for node will use require and will work just fine.

Upvotes: 2

BrunoLM
BrunoLM

Reputation: 100351

On a definition file you have to export enums with declare.

I looked up some examples from DefinitelyTyped, here is one:

export declare enum EDeflateStrategy {
    DEFAULT_STRATEGY = 0,
    FILTERED = 1,
    HUFFMAN_ONLY = 2,
    RLE = 3,
    FIXED = 4,
}

The problem with your code is that your definition file seems to be looking at a .ts file instead of another .d.ts file.

If this is your library and it is written in ts you can just add

"declaration": true

on your tsconfig.json file and let tsc generate the definition for you.

If it is not you can try to mock things from this library in ts and let the tsc generate declarations for you by enabling this option.

Upvotes: 0

Related Questions