Creating a Typescript definition that includes a custom constant enumeration allows for precise

Struggling to generate TypeScript definition files for a specific library.

The library contains a method that requires a parameter of type number, limited to a specific set of numbers. Therefore, I aim to specify in my definition that it necessitates an enum type created using a const enum.

However, upon defining my class within a .d.ts file like this:

// definitions/SimpleDefinition.d.ts

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

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

I define my enum as follows:

// definitions/Enums.ts

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

To link the two, I utilize an index.d.ts:

// definitions/index.d.ts

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

The compiler throws this error message:

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

I attempted adding an import statement at the beginning of my SampleDefinition.d.ts, but this led to the definition not being correctly identified in my code file, despite no errors shown by Visual Studio or Visual Studio Code for the import itself.

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

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

Various attempts have been made, such as experimenting with AMD and relocating files, yet achieving functionality seems elusive. Is there a viable solution? Or must I resort to alternative methods or abandon the endeavor?

A Github repository showcasing this scenario can be found here.

Answer №1

The file SampleDefinition.d.ts lacks top-level import or export statements, whereas Enum.ts includes them. This means that Enums is considered a module, while SampleDefinition is not. However, there is an attempt to use Enums within it. In older terminology, SampleDefinition.d.ts is classified as an internal module and Enums as an external module. Mixing the two in one application is not allowed.

To resolve this inconsistency, there are two approaches:

One solution involves making everything internal without any top-level imports/exports:

In Enum.ts, enclose the export within a namespace:

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

In Main.ts, simply remove the line import Enums ...:

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

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

Alternatively, convert everything into modules:

In SampleDefinition.ts, utilize import instead of reference and switch to exporting the class:

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

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

In Main.ts, explicitly import all dependencies instead of using reference:

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

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

The choice between the two methods depends on your preference. The key distinction is that with modules, the app will need a module loader at runtime. Without modules, it can be compiled into a single script file. This primarily impacts browsers (where you must supply a module loader) as code compiled for Node.js will work with require regardless.

Answer №2

When exporting enums in a definition file, remember to use declare.

I found some examples on DefinitelyTyped, like this one:

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

The issue with your code lies in the fact that your definition file appears to be referencing a .ts file instead of a .d.ts file.

If you own the library and it's written in TypeScript, simply add

"declaration": true

to your tsconfig.json file and let tsc generate the definitions for you.

If it's not yours, you can try mocking things from the library in TypeScript and allow tsc to create declarations by enabling this option.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible to use a Jasmine spy on a fresh instance?

In need of assistance with testing a TypeScript method (eventually testing the actual JavaScript) that I'm having trouble with. The method is quite straightforward: private static myMethod(foo: IFoo): void { let anInterestingThing = new Interesti ...

Is it necessary for NestJS exception filters to handle event emitter errors?

While conducting some manual tests on a revamped NestJS application, I stumbled upon an unusual behavior exhibited by Nest's global exception filter. The developer of this project has implemented the following as an exception filter: import { Excep ...

I have noticed that my unit test case does not include coverage for the if statement

Here is the function I have in my TypeScript file: routeToIndividualPortal(sessionToken: string) { let redirectUrl = this.relayState; console.log("Pre-source-check Indivual URL : " + redirectUrl); let url = ""; if(redirectUrl.includes(this. ...

Exploring the StackNavigationProps and Screen properties in react-navigation v5 for Typescript

When dealing with defining types for a screen's navigation prop in a different file than the router, what is the most effective approach? For example, if I have one file where routes are defined: //Router.tsx type RootStackParamList = { Home: unde ...

Ending the iteration in a TypeScript/JavaScript function by utilizing a for loop within

Currently, I am facing a challenge in breaking an iterative loop and returning false when a specific condition is met. Essentially, my goal is to determine whether a reactive form is empty or not: public isEmpty(form: AbstractControl): boolean { if ...

When setting a value that has been explicitly casted, the original literal type remains intact for the new property or variable

After defining the constant MODE with specific values, I noticed something interesting: const MODE = { NONE: 0 as 0, COMPLETED: 1 as 1, DELETED: 2 as 2 } as const // In a CreateReactApp project, enums aren't available It became appar ...

Using the TypeScript NextPage function along with the getInitialProps static method and @typescript-eslint/unbound-method

After enabling typescript-eslint with its recommended settings, I encountered an issue in my code. I came across this helpful post on Stack Overflow: Using getInitialProps in Next.js with TypeScript const X: NextPage = props => {/*...*/} X.getInitialP ...

Assign each active class name to the Tab components in React

I'm struggling to figure out how to apply an active class to each tab title so that it can have a distinct style when clicked. I'm looking for solutions on how to achieve this within these components, any help is greatly appreciated. App.tsx imp ...

Threading in Node.js for Optimized Performance

Having trouble making axios calls in worker threads Hello, I'm working on a Node.js application and attempting to utilize worker threads for one specific task. Within the worker thread, I need to make an axios call, but I keep encountering an error w ...

The type 'never' does not have a property named 'map'

Whenever I try to make an axios get request within a next.js getServerSideProps function, I encounter a persistent TypeScript error underline on the map method. Despite troubleshooting extensively, I have not been able to resolve it. The request successf ...

Disabling the <md-expansion-panel> in Angular2 Material2: A Step-by-Step Guide

I am encountering some difficulties with the official documentation of material design, they mentioned Expansion panels can be disabled using the disabled attribute. A disabled expansion panel can't be toggled by the user, but can still be manipulate ...

Misunderstanding the concept of always being right

Here is a code snippet that raises an error in TypeScript: class Status { constructor(public content: string){} } class Visitor { private status: Status | undefined = undefined; visit(tree: Tree) { if (tree.value > 7) { this.status = new ...

Describing an Object with some typed properties

Is there a method to specify only a portion of the object type, while allowing the rest to be of any type? The primary objective is to have support for intelliSense for the specified part, with the added bonus of type-checking support. To demonstrate, let& ...

Is it considered safe to modify variables by using this[varName] = something within a function that includes varName as a parameter?

As I continue working on this function, a question arises regarding the safety of changing variables in this manner. In my Angular service, I utilize utility functions where context represents this from the component calling the function. The code snippet ...

How to stop a method in Angular2 when a specific response is received?

I've been grappling with the idea of unsubscribing from a method in Angular2 once it receives a specific response. settings.component.ts Within my component, the method in question is connectToBridge, where the value of this.selectedBridge is a stri ...

Can sweetalert2 be used as a tooltip?

I have a query, is it feasible to include a tooltip in the alert message? Alternatively, could there be another tooltip option available? Swal.fire({ title: '<strong>An example with HTML tags</strong>', icon: 'info', ...

The script resource is experiencing a redirect that is not permitted - Service Worker

I have integrated a Service Worker into my Angular application, and it works perfectly when running on localhost. However, when I attempt to deploy the code in a development or different environment, I encounter the following error: Service worker registra ...

How to use Shell command to transfer only HTML files to the designated directory

Currently working on a build script using npm. This build script involves compiling typescript. During the typescript compile process, it copies the folder structure from a ts directory to a dist/js directory. An example of the structure in the ts folde ...

Creating a Typescript class to mirror the Mongoose model

Currently, I am working on a web application utilizing Angular 2 with TypeScript. The database I am using is MongoDB with a Mongoose framework, and the server is running on Node with an Express framework. The MongoDB and Node code is written in plain JavaS ...

Enhancing the session object with new properties

I am attempting to include extra properties in the session object req.session.confirmationCode = confirmationCode; However, I encounter an error stating that the property confirmationCode does not exist Property 'confirmationCode' does not exist ...