Typescript window as any

How do you explicitly set a new property on `window` in TypeScript?

I setup global namespaces for my objects by explicitly setting a property on window .

window.MyNamespace = window.MyNamespace || <>; 

TypeScript underlines MyNamespace and complains that:

> The property ‘MyNamespace’ does not exist on value of type ‘window’ > any»

I can make the code work by declaring MyNamespace as an ambient variable and dropping the window explicitness but I don’t want to do that.

declare var MyNamespace: any; MyNamespace = MyNamespace || <>; 

How can I keep window in there and make TypeScript happy?

As a side note I find it especially funny that TypeScript complains since it tells me that window is of type any which by definitely can contain anything.

Typescript Solutions

Solution 1 — Typescript

declare global < interface Window < MyNamespace: any; > > window.MyNamespace = window.MyNamespace || <>; 

Basically, you need to extend the existing window interface to tell it about your new property.

Solution 2 — Typescript

To keep it dynamic, just use:

Note that this may not work with TSX because the compiler might think that the is a TSX element. Check out this answer for type assertion that is compatible with TSX.

Solution 3 — Typescript

Using Svelte or TSX? None of the other answers were working for me.

Solution 4 — Typescript

As of TypeScript ^3.4.3, this solution no longer works

And you won’t get a compile error and it works the same as typing window.MyNamespace .

Solution 5 — Typescript

Globals are «evil» 🙂 I think the best way to also have the portability is:

First you export the interface: (for example, ./custom.window.ts)

export interface CustomWindow extends Window < customAttribute: any; > 
import CustomWindow> from './custom.window.ts'; 

Third, cast the global variable window with CustomWindow:

declare let window: CustomWindow; 

In this way you also don’t have a red line in a different IDE if you use it with existent attributes of the window object, so at the end try:

window.customAttribute = 'works'; window.location.href = '/works'; 

Tested with TypeScript 2.4.x and newest!

Solution 6 — Typescript

The accepted answer is what I used to use, but with TypeScript 0.9.* it no longer works. The new definition of the Window interface seems to completely replace the built-in definition, instead of augmenting it.

Читайте также:  Питон пандас руководство на русском

I have taken to doing this instead:

interface MyWindow extends Window < myFunction(): void; > declare var window: MyWindow; 

UPDATE: With TypeScript 0.9.5 the accepted answer is working again.

Solution 7 — Typescript

For those using the Angular CLI, it’s straightforward:

declare global < interface Window < myCustomFn: () => void; > > 
window.myCustomFn = function () < . >; 

If you’re using IntelliJ IDEA, you also needed to change the following setting in the IDE before your new polyfills pick up:

> File > Settings > Languages & Frameworks > TypeScript > check 'Use TypeScript Service'. 

Solution 8 — Typescript

If you need to extend the window object with a custom type that requires the use of import , you can use the following method:

import MyInterface from './MyInterface'; declare global < interface Window < propName: MyInterface > > 

See Global Augmentation in the ‘Declaration Merging’ section of the Handbook.

Solution 9 — Typescript

Create a file called global.d.ts , e.g., /src/@types/global.d.ts , and then define an interface like:

Solution 10 — Typescript

Most of the other answers are not perfect.

  • Some of them just suppress the type inference for show.
  • Some of the others only care about global variables as namespaces, but not as interfaces/classes

I also encountered a similar problem this morning. I tried so many «solutions» on Stack Overflow, but none of them produced absolutely no type errors and enabled triggering type jumping in the IDE (WebStorm or Visual Studio Code).

I found a reasonable solution to attach typings for a global variable that acts as interface/class and namespace both.

// typings.d.ts declare interface Window < myNamespace?: MyNamespace & typeof MyNamespace > declare interface MyNamespace < somemethod?() >declare namespace MyNamespace < // . > 

The code above merges the typings of namespace MyNamespace and interface MyNamespace into the global variable myNamespace (the property of window).

Solution 11 — Typescript

I don’t need to do this very often. The only case I have had was when using Redux DevTools with middleware.

const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; 

let myWindow = window as any;

And then myWindow.myProp = ‘my value’;

Solution 12 — Typescript

After finding answers around, I think this page might be helpful:

I am not sure about the history of declaration merging, but it explains why the following could work.

declare global < interface Window < MyNamespace: any; > > window.MyNamespace = window.MyNamespace || <>; 

Solution 13 — Typescript

From the version 3.4, TypeScript has supported globalThis . See Type-checking for globalThis.

// in a global file: var abc = 100; // Refers to 'abc' from above. globalThis.abc = 200; window.abc = 300; // window object can also be used. 

A «global» file is a file which does not have any import/export statements. So the declaration var abc; can be written in .d.ts.

Solution 14 — Typescript

Using create-react-app v3.3 I found the easiest way to achieve this was to extend the Window type in the auto-generated react-app-env.d.ts :

Solution 15 — Typescript

TypeScript does not perform typechecking on string properties.

window["newProperty"] = customObj; 

Ideally, the global variable scenario should be avoided. I use it sometimes to debug an object in the browser console.

Solution 16 — Typescript

Here’s how to do it, if you’re using TypeScript Definition Manager!

npm install typings --global 
interface Window < MyNamespace: any; > declare var window: Window; 

Install your custom typing:

typings install file:typings/custom/window.d.ts --save --global 

Done! Use it! TypeScript won’t complain any more:

window.MyNamespace = window.MyNamespace || <>; 

Solution 17 — Typescript

If you are using TypeScript 3.x, you may be able to omit the declare global part in the other answers and instead just use:

interface Window < someValue: string another: boolean > 

This worked with me when using TypeScript 3.3, Webpack and TSLint.

Читайте также:  Php распарсить строку по разделителю

Solution 18 — Typescript

window["MyNamespace"] = window["MyNamespace"] || <>; 

should be all right as it is using a string property, but if you really want to have a separated window and organised your code, you can extend the window object:

interface MyNamespacedWindow extends Window < MyNamespace: object; > declare var window: MyNamespacedWindow; 

Solution 19 — Typescript

First you need to declare the window object in the current scope. Because TypeScript would like to know the type of the object. Since the window object is defined somewhere else, you can not redefine it.

But you can declare it as follows:

This will not redefine the window object nor will it create another variable with name window . This means window is defined somewhere else and you are just referencing it in the current scope.

Then you can refer to your MyNamespace object simply by:

Or you can set the new property on the window object simply by:

window.MyNamespace = MyObject 

And now the TypeScript won’t complain.

Solution 20 — Typescript

For reference (this is the correct answer):

Inside a .d.ts definition file

type MyGlobalFunctionType = (name: string) => void 

If you work in the browser, you add members to the browser’s window context by reopening Window’s interface:

declare module NodeJS < interface Global < myGlobalFunction: MyGlobalFunctionType >> 

Now you declare the root variable (that will actually live on window or global):

declare const myGlobalFunction: MyGlobalFunctionType; 

Then in a regular .ts file, but imported as side-effect, you actually implement it:

global/* or window */.myGlobalFunction = function (name: string) < console.log("Hey !", name); >; 

And finally use it elsewhere in the codebase, with either:

global/* or window */.myGlobalFunction("Kevin"); myGlobalFunction("Kevin"); 

Solution 21 — Typescript

Make a custom interface that extends the Window and add your custom property as optional.

Then, let the customWindow use the custom interface, but valued with the original window.

It’s worked with the TypeScript 3.1.3.

interface ICustomWindow extends Window < MyNamespace?: any >const customWindow:ICustomWindow = window; customWindow.MyNamespace = customWindow.MyNamespace <> 

Solution 22 — Typescript

For those who want to set a computed or dynamic property on the window object, you’ll find that not possible with the declare global method. To clarify for this use case

window[DynamicObject.key] // Element implicitly has an 'any' type because type Window has no index signature 

You might attempt to do something like this

declare global < interface Window < [DyanmicObject.key]: string; // error RIP > > 

The above will error though. This is because in TypeScript, interfaces do not play well with computed properties and will throw an error like

A computed property name in an interface must directly refer to a built-in symbol 

To get around this, you can go with the suggest of casting window to so you can do

(window as any)[DynamicObject.key] 

Solution 23 — Typescript

Full & Short answer

1- Add typeRoots property to tsconfig.json :

< "compilerOptions": < . "typeRoots": ["src/@types", "node_modules/@types"] . > > 

2- Extend Window type

// file: src/@types/global.d.ts declare global < interface Window < customProperty: type>; > > 

Solution 24 — Typescript

// In typings.d.ts(is Global) export declare global < interface Window < __PUBLIC__: string; > > 

enter image description here

Solution 25 — Typescript

I wanted to use this in an Angular (6) library today and it took me a while to get this to work as expected.

Читайте также:  Красивый футер на html

In order for my library to use declarations, I had to use the d.ts extension for the file that declares the new properties of the global object.

So in the end, the file ended up with something like:

Once created, don’t forget to expose it in your public_api.ts .

Solution 26 — Typescript

Solution 27 — Typescript

TypeScript prevents accessing an object without assigning a type that has the desired property or already assigned to any , so you can use optional chaining:

Solution 28 — Typescript

I use without declarate. My example looks like:

enter image description here

How do I get list of all tables in a database using TSQL?

What exactly is a Maven Snapshot and why do we need it?

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content Type Original Author Original Content on Stackoverflow
Question joshuapoehls View Question on Stackoverflow
Solution 1 — Typescript joshuapoehls View Answer on Stackoverflow
Solution 2 — Typescript chinupson View Answer on Stackoverflow
Solution 3 — Typescript David Boyd View Answer on Stackoverflow
Solution 4 — Typescript Evan Larsen View Answer on Stackoverflow
Solution 5 — Typescript onalbi View Answer on Stackoverflow
Solution 6 — Typescript Blake Mitchell View Answer on Stackoverflow
Solution 7 — Typescript Stephen Paul View Answer on Stackoverflow
Solution 8 — Typescript Jeff Camera View Answer on Stackoverflow
Solution 9 — Typescript Alex Tran View Answer on Stackoverflow
Solution 10 — Typescript e-cloud View Answer on Stackoverflow
Solution 11 — Typescript Dimitar Nikovski View Answer on Stackoverflow
Solution 12 — Typescript Sheng View Answer on Stackoverflow
Solution 13 — Typescript kena0ki View Answer on Stackoverflow
Solution 14 — Typescript Kris Dover View Answer on Stackoverflow
Solution 15 — Typescript Irshad View Answer on Stackoverflow
Solution 16 — Typescript Nik Sumeiko View Answer on Stackoverflow
Solution 17 — Typescript Dana Woodman View Answer on Stackoverflow
Solution 18 — Typescript Alireza View Answer on Stackoverflow
Solution 19 — Typescript Mav55 View Answer on Stackoverflow
Solution 20 — Typescript Benoit B. View Answer on Stackoverflow
Solution 21 — Typescript shuizhongyuemin View Answer on Stackoverflow
Solution 22 — Typescript aug View Answer on Stackoverflow
Solution 23 — Typescript Masih Jahangiri View Answer on Stackoverflow
Solution 24 — Typescript tomoe View Answer on Stackoverflow
Solution 25 — Typescript Dirk View Answer on Stackoverflow
Solution 26 — Typescript Up209d View Answer on Stackoverflow
Solution 27 — Typescript Mohammed Mamoun View Answer on Stackoverflow
Solution 28 — Typescript bob View Answer on Stackoverflow

Источник

Оцените статью