How Do You Explicitly Set a New Property on window in TypeScript?

When working with JavaScript, it’s common to add custom properties to the window object. However, in TypeScript, you might encounter errors when trying to do this. This happens because TypeScript enforces stricter type checking and doesn’t allow adding properties to window without explicitly declaring them.

Let’s break down how to resolve this issue step by step.

Why Does TypeScript Throw an Error?

In TypeScript, the window object has a predefined type that represents the global scope. This type is fixed and doesn’t include your custom property. If you try to add a new property to window, TypeScript will throw an error like this:

window.myCustomProperty = "Hello, World!"; // Error: Property 'myCustomProperty' does not exist on type 'Window & typeof globalThis'.

This error occurs because TypeScript doesn’t know about myCustomProperty. To fix this, you need to explicitly declare it.

Extending the Window Interface

The solution is to extend the Window interface to include your new property. TypeScript allows you to augment existing interfaces using declaration merging.

Here’s how you can do it:

// Declare your custom property on the Window interface
declare global {
interface Window {
myCustomProperty: string;
}
}
// Now you can safely assign a value to the property
window.myCustomProperty = "Hello, World!";

By declaring the myCustomProperty field inside a declare global block, you’re telling TypeScript that the Window interface now includes this property. This removes the error and allows you to assign a value to it.

Using the Property Safely

After extending the Window interface, you can use your custom property anywhere in your project with full type safety.

if (window.myCustomProperty) {
console.log(window.myCustomProperty); // Output: "Hello, World!"
}

You’ll also benefit from autocompletion and error checking in your editor, which makes working with the custom property more convenient.

Handling Optional Properties

If your property might not always exist, you can make it optional by using a question mark (?) in the declaration:

declare global {
interface Window {
myCustomProperty?: string;
}
}
if (window.myCustomProperty) {
console.log(window.myCustomProperty);
} else {
console.log("Property is not set.");
}

This ensures that TypeScript doesn’t assume the property is always present, helping you avoid potential runtime errors.

Using Custom Properties in Modules

If you’re working in a module-based TypeScript project, ensure your declare global block is included in a .d.ts file or a file that’s loaded globally in your project. For example, create a file named globals.d.ts and add your declaration there:

// globals.d.ts
declare global {
interface Window {
myCustomProperty: string;
}
}
export {}; // This ensures the file is treated as a module.

Including this file in your TypeScript compilation settings ensures the Window interface is properly extended throughout your project.

Conclusion

Extending the Window interface in TypeScript is a simple process that ensures your custom properties are type-safe and error-free. By following these steps, you can confidently add and use custom properties on the window object in your projects, enjoying the full benefits of TypeScript’s type system.

Leave a Reply