I'm writing the type definitions for a library I'm using. One function in the library identifies the mouse button clicked by an integer:
//index.d.ts export as namespace myLib; // activates the library listening for a specific mouse button function activate(button : number ) : void
I introduced an enum to make this nicer:
//index.d.ts export as namespace myLib; export enum MouseButton { LEFT = 1, MIDDLE = 2, RIGHT = 4 } export function activate(button : MouseButton ) : void;
Now, when I import this function and use it, everything compiles but I guess the enum is stripped and undefined when executed in the browser. The error message says Cannot read property 'LEFT' of undefined
.
Therefore I rearranged the files like so:
//MouseButton.ts export enum MouseButton { LEFT = 1, MIDDLE = 2, RIGHT = 4 } //index.d.ts export as namespace myLib; import {MouseButton} from MouseButton; export {MouseButton} from MouseButton; export function activate(button : MouseButton ) : void;
Now I can import {MouseButton} from "myLib/MouseButton"; import * as myLib from "myLib"
. But this requires two imports. Referencing myLib.MouseButton
still compiles but doesn't run.
Is there any way to import and reference the MouseButton
enum via the myLib
imported via the import * as myLib
statement? I'm not only looking for an answer explaining how to do it but for one explaining why my solution doesn't work or why it isn't possible. Hints to resources explaining what's wrong are also appreciated
PS: I also tried the syntax suggested here re-export Typescript enum from namespace? but that didn't work either.
PPS: The module in question is a UMD module from the cornerstone project (https://github.com/cornerstonejs/cornerstone) used in an angular 6 project.
TypeScript uses the concept of modules, in the same way that JavaScript does. In order to be able to import an enum from a different file, it has to be exported using a named or default export.
TypeScript supports export = to model the traditional CommonJS and AMD workflow. The export = syntax specifies a single object that is exported from the module. This can be a class, interface, namespace, function, or enum.
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.
Enums or enumerations are a new data type supported in TypeScript. Most object-oriented languages like Java and C# use enums. This is now available in TypeScript too. In simple words, enums allow us to declare a set of named constants i.e. a collection of related values that can be numeric or string values.
(To complete t.animal's own answer)
Declaration files are difficult to make: see the long documentation. Sometimes looking in existing .d.ts files can help.
Regarding enum
, declaring them as const enum
is a clean and simple approach. It's what is done for jquery for instance, see @types/jquery/index.d.ts for Mouse
and Key
. It's handy because standard enums are compiled in JavaScript as arrays while const enum
members are compiled directly as values ; see TypeScript Playground.
Solved it by the help of Romain Denau's comment above. It nudged me in the right direction: What code does the typescript compiler generate from an enum (see https://www.typescriptlang.org/docs/handbook/enums.html#enums-at-runtime)? Declaring the enum const
allows the typescript compiler to completely swap the identifier with the respective value, effectively inlining it. No more leakage of the enum into the production code. Thanks!
//index.d.ts export as namespace myLib; export const enum MouseButton { LEFT = 1, MIDDLE = 2, RIGHT = 4 } export function activate(button : MouseButton ) : void;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With