Ways to implement a non-Typescript javascript library

Looking into the official guide on module loading in Typescript, I came across a section called "Ambient Modules" which discusses loading modules not written in Typescript. Intrigued, I decided to try implementing this method for a simple learning project.

The goal is to utilize Typescript to load the MyThing.js library below:

// myThings.js
function getMyThing (){
    return "This is my thing";
}

function getMyObject() {
    return {
        a: 1,
        b: "my object"
    }
}

Here is my myThing.d.ts file:

// myThing.d.ts
declare module myThing {
    interface MyObject {
        a: number;
        b: string;
    }

    export function getMyThing():string;
    export function getMyObject():MyObject;

}

Now here's the app.ts that is meant to use the myThing library:

// app.ts
import {getMyThing} from "./myThing.d";

All files - myThing.js, myThing.d.ts, and app.ts - are stored in the same folder. But unfortunately, things aren't going smoothly. Upon compiling app.ts, I encountered the following error:

myThing.d.ts' is not a module. (2306)

So here's my plea: How can I successfully import a non-Typescript module? Do I need to incorporate declare files? If possible, could you please provide some code snippets using the provided demo files?

I've already spent time sifting through the official documentation, but I'm still stumped. Help would be greatly appreciated!

Answer №1

Exporting the module type definition

When TypeScript attempts to import your module, it searches for the relevant file (in this case, myThing.d.ts), and checks if a module with the specified name (getMyThing) is being exported. In this scenario, you have only declared the module without exporting it. To rectify this, modify your .d.ts file as follows:

// myThing.d.ts
export module myThing {
//^ changed 'declare' to 'export'
    interface MyObject {
        a: number;
        b: string;
    }
    export function getMyThing():string;
    export function getMyObject();
}


Correctly importing the module

On compilation after making the changes above, you may encounter the following error message:

app.ts(1,9): error TS2305: Module '"/home/gnalck/workspace/modules/myThing"' does not export 'getMyThing'.

This occurs because you have exported a single logical module myThing. Therefore, revise your import statement like so:

import {myThing} from './myThing';

If you wish to use getMyThing, access it using myThing.getMyThing().


Modularizing the JavaScript file

After making the aforementioned adjustments, when running the code in a platform such as Node.js, you might encounter a runtime error like:

TypeError: Cannot read property 'getMyThing' of undefined
. This issue arises due to the lack of modularity in your JavaScript file.

To resolve this, structure your JS file to mirror the export layout in your .d.ts file. Here's one solution employing CommonJS style:

module.exports = {
  myThing: {
    getMyThing: function () {
      return "This is my thing";
    },

    getMyObject: function () {
      return {
        a: 1,
        b: "my object"
      }
    }
  }
}

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

The eslint command encounters an issue on the CI Server, displaying the error message "ESLint is unable to locate the 'standard' config to extend from."

My local eslint configuration works perfectly fine with vscode editor, but I'm encountering an issue on the CI Server. When running the linting command, I receive the following error: eslint:config-array-factory Config file found: /home/worker/worksp ...

Executing a series of promises sequentially and pausing to finish execution

I have been attempting to run a loop where a promise and its respective then method are created for each iteration. My goal is to only print 'Done' once all promises have been executed in order. However, no matter what I try, 'done' alw ...

Angular is throwing error TS2322 stating that the type 'string' cannot be assigned to the type '"canvas" while working with ng-particles

My goal is to incorporate particles.js into the home screen component of my project. I have successfully installed "npm install ng-particles" and "npm install tsparticles." However, even after serving and restarting the application, I am unable to resolve ...

Monitoring for incoming chat messages

I'm relatively new to Firebase and Angular2. I'm currently working on creating a chat app that integrates Firebase with Angular2 based on tutorials I've been following. Specifically, I've been using this tutorial to build the chat app ...

The Angular router is causing an issue where when navigating back, my component does not reset to 0 as expected, resulting in

I'm currently working on an ionic-angular app and implementing a Register feature where users input their information step by step. The issue I'm facing is with the backward navigation functionality - when users go back using the arrow button, th ...

Angular filter by boolean values

Trying to create a filter based on user status, with "Active" for online and "Inactive" for offline. However, filtering by string is presenting challenges as typing "active" still shows offline users due to the presence of "inactive" within it. I am lookin ...

Mastering Jquery Query Builder within Angular: A Comprehensive Guide

I am exploring how to integrate the jQuery Query Builder into my angular-cli project. Initially, I attempted to use the plugin from laplasianin/angular-jqueryQueryBuilder, but I struggled with importing it into my component due to lack of clear instructio ...

define a variable within a v-for loop

Example of Code <div v-for="item in dataItems"> <div v-if="enableEdit"> <input type="text" v-model="name"> </div> <div v-else> {{name}} </div> <button @click="enableEdit = true">click</button> This ...

The propagation of onClick events in elements that overlap

Having two divs absolutely positioned overlapping, each containing an onClick handler. The issue is that only the top element's onClick handler fires when clicked. React 17 is being used. Here is some sample code: <div style={{ position: "abs ...

Encountered difficulties in deploying functions on Firebase Cloud Functions

While developing the Firebase Cloud Functions, I organized the files based on each function. Unfortunately, numerous errors occurred during deployment. Error [debug] [2022-07-19T14:36:17.677Z] <<< [apiv2][body] GET https://us.gcr.io/v2/xxxxxx/gcf ...

Is it possible to author TypeScript modules in a format other than ES6?

Is it possible to utilize AMD for writing code? define([ 'hb!./some/file.hb' ], function(template) { // }) ...

Exploring the functionalities of Bootstrap tour in conjunction with Typescript

I recently started exploring Typescript and encountered an issue with a project that utilizes bootstrap tour. Up until now, I had been following the basic implementation provided in the bootstrap tour API. However, when transitioning this code to Typescrip ...

Using an alias to call a function defined in a separate module in TypeScript

The following code snippet is from the v4.js file located inside the uuid folder within Angular's node_modules: var rng = require('./lib/rng'); var bytesToUuid = require('./lib/bytesToUuid'); function v4(options, buf, offset) { ...

Tips for setting ngModel and name attributes in an angular test for a custom component

Just getting started with angular. I recently developed a custom component that implements the ControlValueAccessor to allow developers to easily access its value. Here's an example of how it can be used: <app-date [label]="'Date 2&apos ...

Working with Sequelize in a many-to-many relationship and querying with multiple conditions

I am facing a challenge with 3 tables - Product, Category, and ProductCategories. I need assistance in retrieving a product along with its various categories. How can this be achieved? @Table({ timestamps: false }) export class Product extends Model<Pro ...

Angular component classes now use the updated RXJS 6.X syntax, rendering the previously used observable deprecated

Here is the component method I am using: if (id !== undefined && id != null && id !== 0) { this.dataService.getTransactionById(id).subscribe( (tr: ITransactionResponse) => { ...

What is the best way to highlight rows for expansion in a primeng table?

Currently, I am experimenting with primeng table row expansion by following this specific example: https://stackblitz.com/edit/github-7gxyuy?file=src/app/app.component.html Despite my efforts to have each expansion row selected individually, I encountered ...

Customize the termination response using TypeScript

I am trying to change the method res.end with a new signature: res.end = (data: any, encoding: string) However, TypeScript is showing the following error: Type '(data: any, encoding: string) => void' is not compatible with type '{ ( ...

Angular : How can a single item be transferred from an array list to another service using Angular services?

How to Transfer a Single List Item to the Cart? I'm working on an Angular web application and I need help with transferring a single item from one service to another service and also displaying it in a different component. While I have successfully i ...

Error message: The specified type is incomplete and lacks certain properties, according to Typescript

I'm encountering an error that's hindering the deployment of my website on Vercel. Any assistance would be greatly appreciated. Usually, I retrieve the pageInfo data from Sanity and use it on my website. The issue lies in this peculiar TS error t ...