What is the best way to make a class available in the global namespace within a TypeScript module?

The Issue at Hand

Given an existing application with a mixture of modules and global scripts, the goal is to convert one class in a global script (gamma.ts) into a module. This entails adding `export default` before `class gamma {}` in gamma.ts. Additionally, the objective is to import the gamma class into the global namespace (window object) for accessibility by both global and module scripts.

Approaches Taken So Far

Several attempts have been made involving global.d.ts file.

For instance:

import gammaAlias from "../scripts/gamma";
export as namespace NS_Global;

declare global {
    var qqq: {n:string};
    namespace ZZZ {
       export var gamma: gammaAlias;
    }
    var gamma: gammaAlias;
}

Despite these efforts, TypeScript has thrown errors such as "gamma does not exist" or "Cannot use 'new' with an expression whose type lacks a call or construct signature."

Exploring on GitHub

To delve deeper into this issue, check out my GitHub repository: https://github.com/penguin020/expose-typescript-modules-globally

The ConvertToModulesPOC_original represents the functional "before" scenario.

In contrast, ConvertToModulesPOC signifies an unsuccessful effort to convert gamma .ts to a module and expose it globally.

Final Notes

The core question remains - how can a module be exposed to the global namespace? Any insights utilizing the provided examples in the GitHub repository would be highly appreciated!

Answer №1

I stumbled upon a solution in the article "TypeScript: exposing module types in the global context and why to avoid it";

After reading, I made updates to the repository on GitHub.

The key changes that caught my attention were:


in tsconfig:

"module": "system",

within yMod.ts

import gammaAlias from "../scripts/gamma.js";

declare global {
    export type gamma = gammaAlias;
    export const gamma: typeof gammaAlias;
}

(window as any).gamma = gammaAlias;

Note: The global ambient declaration could also be placed in another file, even a *.d.ts file.


The provided link explains the rationale behind having three references for each symbol to be exposed globally. The page elaborates well on this topic, so here's a brief summary:

  1. Expose the class type to the TypeScript compiler (no code generated)
  2. Expose the class object to the TypeScript compiler (to allow instantiation with new; no code generated)
  3. Extend the window object to expose the class in the global namespace (generates code).

Answer №2

If I understand correctly, your goal is to make 'gamma' accessible in the global scope for easy access to 'gamma.log()' from either 'window' or the console.

To achieve this, insert the following 2 lines at the end of the gamma.ts file:

let g = new gamma();
(window as any).gamma = g

Explanation:

1) The first line creates a new instance of the Gamma class and stores it in the variable g.

2) The second line makes g available globally under 'window.g' or simply 'g'.

See the screenshot for reference: Screenshot

For further details, refer to Pull request #1: https://github.com/penguin020/expose-typescript-modules-globally/pull/1/files


It may be beneficial to move these code lines to your main initialization file 'app.js' for better organization.

Contents of gamma.ts:

export default class gamma {

Contents of app.ts:

import gamma from "./gamma";
let g = new gamma();
(window as any).gamma = g

Find more information in Pull request #2: https://github.com/penguin020/expose-typescript-modules-globally/pull/2

Answer №3

This solution fits perfectly with my needs. The only thing I find inconvenient is having to change the interface name.

declare global {
  interface IMyClass extends MyClass { }
}

class MyClass {

}

or

declare global {
  type IMyClass = MyClass;
}

class MyClass {

}

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

Having trouble grasping the concept of Interfaces and dealing with FormGroup problems in Angular?

Apologies if my question is a duplicate, I have found several solutions for the same issue on Stack Overflow, but unfortunately, I struggle to understand them in technical terms. Problem 1 src/app/models/dataModel.ts:2:5 2 id: number; ~~ The exp ...

How to select a DOM element in Angular 2.x

Although it may seem simple, there are not many examples of using Angular 2.0 yet. In one of my components, I have a situation where I need to add a class to the body tag. However, my application is bootstrapped deeper than the body element, so I am looki ...

Is it possible to utilize an XML format for translation files instead of JSON in React Native?

I'm in the process of creating a react native application using the react i18next library. For translations, I've utilized XML format in android for native development. In react native, is it possible to use XML format for translation files inste ...

Oops! We encountered an error: Uncaught (in promise): [object Object]. Angular 5 version is

Trying to implement an upload button using Angular 5, I have the following code in my .ts file: handleFiles(e) { this.file = e.srcElement.files[0]; if (this.file.size > 2097152) { let snackBarRef = this.snackBar.open('Images must ...

Error display in Elastic Apm Rum Angular implementation

Having some issues with incorporating the @elastic/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f5948598d8878098d8949b9280999487b5c7dbc4dbc4">[email protected]</a> package into my project. Angular is throwing console ...

How to assign attributes to all child elements in Angular?

I have a unique component in Angular that I utilize throughout my app. It's a button component which I use by calling <app-delete-btn></app-delete-btn> wherever needed. I tried to set the tabindex="1" attribute for my component ...

Typescript: Omitting mandatory fields from a type

Can anyone help me with defining the type ExcludeAllRequiredProps<T> in the code below to exclude all required properties? Any assistance would be greatly appreciated. Thank you. type A = { a: number, b: number, c?: number, d?: number } typ ...

Tips on showcasing lengthy string content from JSON in a structured list format using react with typescript

Is there a way to display long string data from a JSON file in a list format when the description string is too lengthy? How can I split or format the description using React and TypeScript? The JSON data I have is as follows: "options": [ ...

What should be the datatype of props in a TypeScript functional HOC?

My expertise lies in creating functional HOCs to seamlessly integrate queries into components, catering to both functional and class-based components. Here is the code snippet I recently developed: const LISTS_QUERY = gql` query List { list { ...

Typescript compilation fails to include require statements in certain files

Currently, I am in the process of converting a Node.js project to TypeScript. The first two main files of the Node project transpiled correctly, but the third file ran into issues with the requires statement at the top for pulling in dependencies. Despite ...

Is there a syntax available for type annotation of arrays created from pre-declared variables?

According to my standards, all possible annotations are required in TypeScript. Therefore, TypeScript-ESLint is prompting me to annotate the `[ responseData, cognitoUser ]`. However, when I try to use the syntax `[ responseData1: ResponseData1, responseD ...

Encountering type errors in NextJS with TypeScript

I am facing an issue while trying to run this function: "use server"; export const addProduct = async (formData: FormData, imageUrl: string) => { const productName = formData.get("productName")?.toString(); const description = f ...

Mocked observables are returned when testing an Angular service that includes parameters

I'm currently exploring various types of unit testing and find myself struggling with a test for a service once again. Here is the function in my service that I need to test: Just to clarify: this.setParams returns an object like {name: 'Test&ap ...

Execute the function right away and then at regular intervals of X seconds

Need help with Angular 7 function call timing checkData(): Observable<string> { return this.http.get('') .pipe( map(res => { let result; result = { packageNumbe ...

Replace Formik with useFormik to streamline your code

I have implemented Formik/Yup for validation on a page that triggers a GraphQL mutation. The code is functioning as expected: export default function RemoveUserPage() { const [isSubmitted, setIsSubmitted] = useState(false); const [isRemoved ,setIsRemo ...

Using Tailwind classes as a prop functions correctly, however, it does not work when directly applied

Here's a component snippet I'm working on: export const TextInput = ({ label, wrapperClassName = "", inputClassName = "", labelClassName = "", placeholder = "", ...props }: InputProps & Fiel ...

What is the process for running a continuous stream listener in a node.js function?

I am currently working with a file called stream.ts: require('envkey') import Twitter from 'twitter-lite'; const mainFn = async () => { const client = new Twitter({ consumer_key: process.env['TWITTER_CONSUMER_KEY'], ...

Is it possible to execute user-defined functions dynamically in a Node.js application without having to restart the server

I am exploring the potential for allowing users to insert their own code into a Node application that is running an express server. Here's the scenario: A user clicks 'save' on a form and wants to perform custom business validations. This ...

What is the significance of TypeScript's dual generic typing feature?

defineListenerShape< EventName extends string, EventData extends { [key in EventName]: unknown; } > = <E extends EventName>(data: EventData[E]) => void; enum EventName { Click = 'click', Hover = 'hover' ...

What steps should I take to fix this TypeScript error?

I've been struggling to fix this error, but I'm unsure of the best way to resolve it. Here is the code snippet I've been working with: Here is the specific error message: ...