Expanding universal types (such as "Window") within a TypeScript module

When working with TypeScript and not using modules, it is possible to extend the global Window object. For instance, the following code will compile:

interface Window {
    myCounter: number;
}

window.myCounter = window.myCounter || 0;
++window.myCounter;

function outputLoadingDetails() {
    console.log(`myCounter= ${window.myCounter}`)
}

However, if the function outputLoadingDetails is prefixed with export, it seems to convert the file into a module. This results in a compiler error when trying to access window.myCounter.

interface Window {
    myCounter: number;
}

window.myCounter = window.myCounter || 0; // ERROR: property 'MyCounter' does not exist on type `Window`
++window.myCounter;                       // ERROR: property 'MyCounter' does not exist on type `Window`

export function outputLoadingDetails() {
    console.log(`myCounter= ${window.myCounter}`)  // ERROR: property 'MyCounter' does not exist on type `Window`
}

It seems that the interface declaration no longer extends the global Window type.

An alternate solution is to place the interface declaration in a separate *.d.ts file and reference it from within the module.

Now the question arises: Is there a way to extend the Window interface within the module code itself?

Answer №1

A simple solution is to enclose the interface within a global declaration like this:

declare global {
    interface Window {
        myCounter: number;
    }
}

You can extend the global scope from modules by using declare global declarations.

For more details, check out this resource.


** Remember to treat the file as a module (include an import or export statement); if not, you can add an empty export {} block.

Answer №2

Adjusting the global declaration was not ideal for me because any changes made would affect other files as well.

To resolve this issue, I implemented the following solution:


interface customWindow extends Window {
  customProperty?: any;
}

declare const window: customWindow;

/* ... */

window.customProperty

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

What is the best way to retrieve messages from a websocket server and display them on an Angular component

Currently, I am in the process of learning how to integrate live chat into an Angular project using Socket.IO. Following a tutorial that I stumbled upon, which can be found here. Incorporating an input box within my component has allowed me to successfull ...

Steps for generating an instance of a concrete class using a static method within an abstract class

Trying to instantiate a concrete class from a static method of an abstract class is resulting in the following error: Uncaught TypeError: Object prototype may only be an Object or null: undefined This error occurs on this line in ConcreteClass.js: re ...

Dealing with side effects in react/redux: Best practices and tips

Trying to find the best way to integrate an async side-effects handler into my react/redux setup has been quite a challenge. In my react-router-driven application, all the main containers at root level are smoothly dispatching actions and receiving update ...

How can I create an endless animation using Angular6?

I created a 3D truck using HTML and CSS. The truck tires rotate 360 degrees if a variable (x) is true. If x is false, the rotation of the truck tires stops. This was achieved in CSS by setting the rotation to infinite. .wheel { animation: round 2s infi ...

Perfecting compound types

Having trouble with this code snippet: type FormatTypes = { text: string, binary: Array<number> }; type Format = keyof FormatTypes; type FormatType<F extends Format> = FormatTypes[F]; type Formatter = { format<F extends Format& ...

Avoiding the pitfalls of hierarchical dependency injection in Angular 6

Too long; didn't read: How can I ensure that Angular uses the standard implementation of HttpClient in lower level modules instead of injecting a custom one with interceptors? I have developed an Angular 6 library using Angular CLI. This library expo ...

Create a Bar Graph Using a List

Looking to generate an Angular Barchart from a JPA query in Spring: public List<PaymentTransactionsDailyFacts> findPaymentTransactionsDailyFacts(LocalDateTime start_date, LocalDateTime end_date) { String hql = "SELECT SUM(amount) AS sum_volume, ...

Unable to load custom package in Angular 2 testing environment

I've been following the official Angular 2 testing guide on an existing project. Everything runs smoothly when I use my custom library, downloadjs, in the application. However, I encounter an error in the console during test execution: "__zone_symbol ...

Ways to confirm the visibility of a web element on the screen with serenity-js

In the current project, I am utilizing the Serenity-js BDD framework with a screenplay pattern approach. However, I am encountering an issue when attempting to assert the visibility of an element on a web page using the "that" method from the Ensure class. ...

Establishing the initial state within the constructor of a React Component utilizing a generic state

I have encountered an issue with React and Typescript. I am working on a component that utilizes two generics for props and state. interface Props { foo: string; } interface State { bar: string; } class Foo< P extends Props = Props, S e ...

What is the reason for the regeneration of the 2D array?

I have a method called generateWeights() that retrieves random values in an array; And a method named learn() that calls the changeWeights() method to alter the values in the array. Expected: Prior to invoking the learn() method, I anticipate receiving an ...

Is it possible to use null and Infinity interchangeably in JavaScript?

I've declared a default options object with a max set to Infinity: let RANGE_DEFAULT_OPTIONS: any = { min: 0, max: Infinity }; console.log(RANGE_DEFAULT_OPTIONS); // {min: 0, max: null} Surprisingly, when the RANGE_DEFAULT_OPTIONS object is logged, i ...

Using the hook to implement the useContext function in React

I came across this definition export interface user{ email:string name:string last_name:string } export type UserType= { user: user; setUser:(user:user) => void; } const [user,setUser] = useState <user> ({ email ...

Store the HttpRequest value within the component

I am encountering an issue with the Http Request value. I am sending an Http request to an Express API rest, and I want to display the value throughout my component. The data is available in the observable but not in other functions of my component. Can ...

Tips for sorting data based on duplicate dates within a single array element

Here is the existing Object Array structure: [ { "date":"12-09-2019 12:00 PM", "id":"1", "name":"hello1" }, { "date":"12-09-2019 03:00 PM", "id":"2", "name":"hello2" }, { "date":"12- ...

An issue arises following an upgrade in Angular from version 9 to version 10, where the property 'propertyName' is being utilized before it has been initialized

I've spent time looking on Google, Github, and Stackoverflow for a solution to this error, but I'm still struggling to fix it. Can anyone offer a suggestion or help? Recently, I upgraded my Angular project from version 9 to version 10, and after ...

Ways to properly assign a key in a Generic Interface as the interface key

Can someone assist me with TypeScript generics? I am wondering how to access the T["value"] field within the ActionAdd interface. type UserValue = { username: string; }; interface User { id: number; value: UserValue; } interface ActionAdd<T = unkn ...

In TypeScript, create an object with a set number of key-value pairs, denoted

As a newcomer to Typescript, I want to create interfaces for the JSON data shown below: { "company":"abc inc", "logoUrl":"someUrl", "phone":"1234567890", "branch":{ "nyc":{ "products":{ "asian":{ ...

I seem to be invisible to the toggle switch

I currently have a toggle button that controls the activation or deactivation of a tooltip within a table. Right now, the tooltip is activated by default when the application starts, but I want to change this so that it is deactivated upon startup and on ...

Step-by-step guide on adding a command to a submenu through the vscode extension api

I'm developing a Visual Studio Code extension and I want to include a command in a submenu like this https://i.stack.imgur.com/VOikx.png In this scenario, the "Peek" submenu contains commands such as "Peek Call Hierarchy". My current Package.json fi ...