What is the best way to incorporate a @types module into a TypeScript file that is not already a module?

Setting the Stage:

In the process of shifting a hefty ~3,000 line inline <script> from a web-page to a TypeScript file (PageScripts.ts) to be utilized by the page through

<script src="PageScripts.js" defer></script>
.

This script entails SortableJS which boasts an available @types package. You can access the *.d.ts files on GitHub here: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/sortablejs

The Original Script Snippet:

Here's a snippet from the original JavaScript in the HTML page causing issues:

<script type="text/javascript">

window.addEventListener( 'DOMContentLoaded', function() {

    var sortableOptions = {
        dataIdAttr: 'my-id',
        onEnd: function( ev ) {

            // do stuff
        }
    };

} );

</script>

I incorporated the @types by executing

npm install --save @types/sortablejs
.

My tsconfig.json resembles this:

  {
        "compileOnSave": true,
        "compilerOptions": {
            "noImplicitAny": true,
            "strict": true,
            "noEmitOnError": true,
            "removeComments": true,
            "sourceMap": true,
            "target": "es5" /* es5 for IE11 support. */,
            "typeRoots": [
                "node_modules/@types",
                "JSFiles/System.Web.dll/Types"
            ],
            "lib": [
                "es5",
                "dom",
                "dom.iterable",
                "es2015.core",
                "es2015.collection",
                "es2015.symbol",
                "es2015.iterable",
                "es2015.promise"
            ]
        },
        "exclude": [
            "node_modules"
        ]
    }

Transitioning to TypeScript:

The aforementioned script fragment was transformed into TypeScript in PageScripts.ts:

import Sortable = require("sortablejs");

// ...

window.addEventListener( 'DOMContentLoaded', function() {

    var sortableOptions = {
        dataIdAttr: 'my-id',
        onEnd: function( ev: Sortable.SortableEvent ) {

            // do stuff
        }
    };

} );

This compiles without errors, but due to the single import statement, TypeScript compiles the file as its JavaScript module, rendering it incompatible for direct use in web-pages. TypeScript appends this line to the beginning of the output PageScripts.js file:

Object.defineProperty(exports, "__esModule", { value: true });

This provokes a browser script error as exports is not defined.

To counter this, I opted for

/// <reference types="sortablejs" />
:

/// <reference types="sortablejs" />

// ...

window.addEventListener( 'DOMContentLoaded', function() {

    var sortableOptions = {
        dataIdAttr: 'my-id',
        onEnd: function( ev: Sortable.SortableEvent ) {        <--- "Cannot find namespace 'Sortable'."

            // do stuff
        }
    };

} );

However, PageScripts.ts fails to compile as tsc throws a "Cannot find namespace 'Sortable'" error.

The IDE suggests importing

import Sortable = require("sortablejs")
as the fix, yet this reverts PageScripts.js back to a module, causing frustration!

Changing module: 'none' in tsconfig.json is not an option as other TypeScript files in the project are modules and altering global settings is undesirable. Is there a way to configure per-file modules?

The Dilemma:

Hence, the big question: How can I utilize the types from @types/sortablejs without transforming my PageScripts.js into a module?

Answer №1

Consider incorporating the d.ts files for sortablejs into the includes array within the tsconfig.json file. This integration will ensure that the library is accessible globally.

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

Tips for concentrating on the initial input field produced by an ng-repeat in AngularJS

Currently, I am dynamically generating input fields using ng-repeat and everything is working smoothly. However, my requirement is to set focus on the first input that is generated by this ng-repeat based on their sequenceId values. So far, I have attempte ...

Guide to creating a versatile navigation bar using Bootstrap and HTML

I am looking to create a navigation menu that can be easily reused across multiple pages on my bootstrap/html website. Instead of duplicating code, I want to implement a solution for creating a reusable navigation menu in bootstrap/html. How can this be ...

Error: The system encountered an issue while trying to access an undefined property 'find'

I've been working on developing the backend for a wishlist feature, but I've encountered an issue with my code. (node:19677) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'find' of undefined Despite trying to redefi ...

Unable to redirect to Jade page in Node.js

I recently delved into the world of node js a few days ago. When I click on a button, a function with an ajax call is triggered. function goToUser(){ $.ajax({ url:"/users/UserPage", type:'get', async:false, su ...

Prevent the event listener from continuously triggering

I have a situation where every time I create an Angular component, an event listener is added. However, upon leaving the page and returning to it, a new event listener is added because the constructor is called again. The problem arises when this event is ...

Troubles with AJAX and jQuery

<html> <head> <title>Ajax Example</title> <script type="text/JavaScript" src="jquery-1.5.1.min.js"></script> <script type="text/JavaScript"> function fetchData() { $.ajax({ type: "GET", url: "htt ...

Guide on verifying the status of a switch toggle using Selenium and C#

I am having trouble verifying the current state of a switch ('on' or 'off') using selenium. The toggle appears in the 'on' position when the webpage loads, but it affects filter results in a table when switched off. I am unabl ...

The functionality of reordering columns, virtual scrolling, and resizing the grid in jqgrid are not functioning properly

Implementing jqgrid with Symfony to display a datagrid has been a challenging task for me. Thanks to Oleg's insightful response, many of the major issues have been resolved. Below is a snippet of my code: <link rel="stylesheet" type="text/css" ...

The functionality of the Drawer component in material-ui v1.0 seems to be incompatible with TypeScript

Every time I try to utilize Drawer from [email protected] using typescript, I encounter the following error: TS2322: Type '{ children: Element; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & Re ...

Each loop in the forEach function triggers the mouseup event

I am currently utilizing a foreach loop: objects.forEach(function(object) { var button = '<tr><td>' + object.object.code + '</td><td>' + formatDistance(1456000) + &apos ...

In JavaScript, a variable's value can be assigned to another variable using the variable

I have a collection of predetermined variables. I dynamically assign a value to another variable, which ends up representing the name of one of the predefined variables. This allows me to easily determine which set variable to use on a particular section o ...

Can you please explain why I am unable to remove the item in my code using Node.js and Express?

Currently, I am in the process of learning NodeJS and working on an application that involves adding Bicicleta objects. However, I have encountered an issue where I am unable to delete these objects successfully. Even though the POST request for deletion r ...

What is the best way to import assets from an NPM-powered package in a PHP composer-based package?

First and foremost, let's clarify that this is not a question about incorporating an NPM package as a dependency of a Composer package. Direct usage of NPM or a composer plugin can easily solve that issue. If we have loaded an NPM package as a depend ...

Developing a standard jQuery function for adding event listeners

Attempting to replicate the functionality of Google Maps' addListener using jQuery listeners for clicks, keypresses, etc. In Moogle Maps, you can use .event.addListener(map, 'click', function()... or switch 'click' with 'drag ...

Obtain the ViewContainerRef object from the Component

Looking to create nested components in Angular 4? This is the Chooser Component import {InputComponent} from './input/input.component' import {BlockComponent} from './block/block.component' export const FormChooser = { Block: Block ...

Message display showing an "[object Object]" (Node Express Passport)

Having an issue with my passport.js implementation where the flash message is not showing up when the username or password is incorrect. The logic was working fine before, but now it's broken even after copying the working version step by step. Flash ...

Unable to retrieve the saved user from the Express.js session

Below is the code in question: app.post('/api/command', function (req, res, next) { var clientCommand = req.body.command; console.log("ClientCommand: ", clientCommand); if (!req.session.step || req.session.step === EMAIL) { ...

Modifying the Trim Function in AngularJS

Using AngularJS version 1.5.6, I encountered a bug in my large application due to the default behavior of trimming input for text type inputs. Wanting to change this behavior globally without manually updating every textarea and text input element, I am se ...

Getting callback data from a function in the AWS SDK without using asynchronous methods

I have a code snippet that fetches data from AWS using a function: main.js const { GetInstancesByName } = require("./functions"); var operationmode = "getinstances"; if (operationmode == "getinstances") { let getresult = ...

How to effectively implement addEventListener() / attachEvent()?

Can anyone provide guidance on how to correctly use addEventListener and attachEvent? window.onload = function (myFunc1) { /* do something */ } function myFunc2() { /* do something */ } if (window.addEventListener) { window.addEventListener('load ...