Having trouble accessing functions in Typescript when importing JavaScript files, although able to access them in HTML

Recently, I started incorporating TypeScript and React into my company's existing JavaScript code base. It has been a bit of a rollercoaster ride, as I'm sure many can relate to.

After conquering major obstacles such as setting up webpack correctly, configuring and implementing tsconfig files, and organizing the bundling process effectively, I have successfully integrated everything with our current CI pipeline.

However, I am currently facing an issue with importing JavaScript libraries in my TypeScript code. While I understand that this is not best practice, it serves as a temporary solution before transitioning to full TS compliance.

I have a basic component that compiles without any issues:


import * as React from "react";
import * as ReactDOM from "react-dom";
import { Header } from "./components/header";
import * as $C from "./../../fortress.content.js";
import * as $F from "./../../fortress.js"; 

let url : string  = $F.writeUrl("Account", "LoginAjax");

ReactDOM.render(
    <div>
        <div> {url} </div>
    </div>,  
    document.getElementById("body")
);

The $F.writeUrl function allows us to generate a string based on a webconfig file located at the root of the project. Essentially, it takes multiple parameters and returns a formatted string based on them.

However, when I run the transpiled JavaScript in an HTML file:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<div id="body"></div>
<div id="header"></div>
<body> 
    <script src="js/jquery-2.1.4.min.js"></script> 
    <script src="js/react-0.14.3.js"></script>
    <script src="js/react-dom-0.14.3.js"></script> 
    <script src="js/filemanager/filemanager.bundle.js"></script>
    <script src="js/anothermanager/anothermanager.bundle.js"></script>
    <script>  
            console.log("$F: ", $F);
            console.log("$C: ", $C);
    </script>
</body>
</html>

The following errors occur:


Uncaught TypeError: Cannot read property 'bind' of undefined
    at new t (filemanager.bundle.js:1)
    at ReactCompositeComponentWrapper.mountComponent (react.js:5504)
    at ReactCompositeComponentWrapper.wrapper [as mountComponent] (react.js:12346)
    at Object.mountComponent (react.js:12971)
    at ReactDOMComponent.mountChildren (react.js:11685)
    at ReactDOMComponent._createContentMarkup (react.js:6817)

anothermanager.bundle.js:1 Uncaught ReferenceError: $C is not defined
    at anothermanager.bundle.js:1
    at Object.<anonymous> (anothermanager.bundle.js:1)
    at n (anothermanager.bundle.js:1)
    at Object.<anonymous> (anothermanager.bundle.js:1)
    at n (anothermanager.bundle.js:1)
    at anothermanager.bundle.js:1
    at anothermanager.bundle.js:1
    at ReactDOMComponent.mountComponent (react.js:6705)
    at Object.mountComponent (react.js:12971)
    at ReactCompositeComponentWrapper.mountComponent (react.js:5581)
    at ReactCompositeComponentWrapper.wrapper [as mountComponent] (react.js:12346)

index.html:17 Uncaught ReferenceError: $F is not defined
    at index.html:17

To resolve this, I attempted to instantiate $C and $F within my TypeScript code:


let test = $F;
let test2 = $C;

This eliminated the above errors and displayed the $F and $C objects in the console log. However, the issue now is that Chrome does not recognize

$F.writeUrl("Account", "LoginAjax")
as a function.

Have I made any mistakes with my imports?

Answer №1

It seems that importing those files into your react bundle may not be necessary. If the files do not export anything with module.exports or export, but instead set up members on the window object to be used later (as was common practice in the past), then you can follow these steps:

1) Include those files as scripts so they are globally accessible. Make sure to include them before any scripts related to react, ensuring they are available when the react code is mounted:

<script src="js/jquery-2.1.4.min.js"></script>
<script src="js/path-to-fortress-content.js"></script>
<script src="js/path-to-fortress.js"></script> 
<script src="js/react-0.14.3.js"></script>
<script src="js/react-dom-0.14.3.js"></script>

2) Now, these files are accessible in your react code. You will need to access them from the window object instead of directly using $F/$C modules in order for your bundler to handle them properly:

let $f: any = (window as any).$F;
let url : string  = $F.writeUrl("Account", "LoginAjax");

Answer №2

[...] incorporating JavaScript libraries into my TypeScript code. Although some may consider it bad practice, I see it as a necessary step before achieving full TS compliance

No need to fret, it's not always frowned upon, especially when in the midst of a transitional phase.

In addition to Sergeon's answer, which addresses the implementation issue, it is worth noting that certain JavaScript libraries do come with typings that allow for their use in TypeScript applications. One example is jQuery:

npm i --saveDev "@types/jquery"

To utilize these typings in a .ts module:

import "jquery";
declare const $: JQueryStatic;

This approach also provides the added benefit of IDE IntelliSense assistance:

https://i.stack.imgur.com/g5yAD.png

If you wish, you can explore and include other libraries from the @types/ repository.

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

Issue with logging messages using console.log in Knex migration script

My concern: I am facing an issue where the console.log('tableNobject: ', tableNobject) does not get logged in my knex migration script. I have attempted the following code snippets: //solution A export async function up(knex: Knex) { const ta ...

Exploring the Power of PrimeNG and Observables in Angular 4 with RxJS

After configuring my Angular 4 project with a service like this: const usersURL = 'http://my.super.url.php'; @Injectable() export class UserService { users: Observable<User[]> constructor (public http:Http) let tick$ = Observ ...

Issue with JQuery Validation: Some checkbox values are not being successfully posted

Currently experiencing issues with validating checkboxes. Utilizing the jQuery plugin validation found here: The scenario is that there are three checkboxes and at least one of them must be checked. The original form code for these checkboxes is as follow ...

Uncovering the Full Scope of a LinkedIn Profile with Typescript

Hello, I am currently in the process of developing an Ionic2 framework app that includes social login functionality. Up to this point, I have successfully integrated Google Plus and Facebook buttons. Now, I would like to add LinkedIn login as well. The c ...

Contrasting bracket notation property access with Pick utility in TypeScript

I have a layout similar to this export type CameraProps = Omit<React.HTMLProps<HTMLVideoElement>, "ref"> & { audio?: boolean; audioConstraints?: MediaStreamConstraints["audio"]; mirrored?: boolean; screenshotFormat?: "i ...

An unexpected page transition occurs when attempting to delete a link

I've successfully created an HTML table that dynamically adds rows and provides an option to delete the current row. Each row represents data retrieved from MongoDB, and upon clicking the delete button, I aim to delete the corresponding item from the ...

Passing a variable to a modal in AngularJS

In my project, I am utilizing https://github.com/simpulton/angularjs-wizard and have made some modifications to it (specifically changed var app to $scope). It is functioning well, however, I am facing an issue where I need to pass a variable to the open f ...

TypeScript Yup schema validation combined with the power of Type Inference

I currently have a unique data structure as shown below: type MyDataType = | { type: "pro"; content: { signedAt: string; expiresOn: string }; } | { type: "default" | "regular"; content: { signed ...

Tips for extracting parameters from a JSON String using JavaScript

When attempting to parse a JSON String, I am encountering an issue where the parsed value is coming up as undefined. You can view the code on this jsfiddle link. <input type="submit" onclick=testJSON() value="Test"/> <div i ...

Arrange the Proxy Array of Objects, the localeCompare function is not available

Encountering an error while attempting to implement ES6 arrayObj.sort(a,b) => a.property.localeCompare(b.property) syntax: Getting TypeError: a.property.localeCompare is not a function. Suspecting that localeCompare might not be in scope, but unsure ...

Ensure that at least one mandatory field is implemented with React final form

Here is a code snippet that handles field validation: export const isOneFieldValid = (val: string) => { console.log(val) return val ? undefined : true } ... const validate = (field: string) => { switch (field) { case 'email': { ...

Creating a dynamic dropdown menu based on a class value using JavaScript in PHP

There are two dropdown menus on my webpage that display information from my SQL table. The first dropdown contains different "Colors," and the second dropdown contains members associated with each color group. Each member is categorized into different optg ...

Issue with the transmission of FormData and string data to PHP

Struggling to properly handle sending file data and string data together through ajax to PHP. Having trouble retrieving the correct string data from $_POST[] in PHP, resulting in only receiving the initial alphabet of a string instead of the specific produ ...

The issue persists as AJAX data and text box data are not being saved simultaneously

I need assistance with an Ajax setup. I am trying to pass the screenwidth information along with a user input value from a text box to a PHP page. However, I am encountering issues as the only value being passed is from the textbox and the other one is sho ...

Send information using jQuery AJAX

Currently, I am attempting to use AJAX to submit data to my table. Below is the form I have created for this purpose: <form> Total <input type="text" id="total" name="total" /><br /> Bill name<input type="text" id="bill-name" ...

Issue with accessing data in React Admin Show Page using useRecordContext() function leads to undefined return

Within a basic RA application, I am attempting to showcase an item known as a "card" utilizing a Show Page. The fields—specifically id and title—are being presented correctly. Nevertheless, the useRecordContext() hook is consistently returning undefin ...

apply a course to the designated element

Alright, I have this piece of code that deals with session and page requests. // Let's start our session session_start(); // Now let's check if there is a page request if (isset($_GET['page'])) { // If there is a requested page, we ...

Oops: Looks like there is already a request for 'PUBLIC_requestAccounts' pending from http://localhost:3000. Just hold tight for now

There comes a moment when an unexpected error arises and fails to establish a connection with your wallet. if (window.ethereum) { console.log("11") const connect = async () => { const account = await window.ethereum.request({ ...

Leveraging the import statement within lib.d.ts to enhance Intellisense functionality in Visual Studio Code

Looking to streamline my JavaScript project by utilizing custom global variables and harnessing the power of VSCode intellisense for auto completion. Here's what I'm aiming for: See example of auto completion for 'lol' After some sear ...

Is there a way to detect when a CSS background image has finished loading? Does an event trigger upon completion?

I am facing an issue with my sidebar widget where there is an image background in place. On top of this, I have a search input form but I don't want the input to display until the image has fully loaded. Is there a way to add a load event handler to ...