TypeScript error: Property 'X' does not exist on type 'Window'
Asked Answered
D

12

274

I have added TS to my React/Redux app.

I use window object in my app like this:

componentDidMount() {
  let FB = window.FB;
}

TS throws an error:

TypeScript error: Property 'FB' does not exist on type 'Window'. TS2339

I want to fix the error.

1 (doesn't work)

// Why doesn't this work? I have defined a type locally

type Window = {
  FB: any
}

componentDidMount() {
  let FB = window.FB;
}

// TypeScript error: Property 'FB' does not exist on type 'Window'. TS2339

2 (fixes the error)

I found the answer here https://mcmap.net/q/45448/-how-do-you-explicitly-set-a-new-property-on-window-in-typescript

declare const window: any;

componentDidMount() {
  let FB = window.FB;
}
// No errors, works well

Why doesn't the first version work, but the second does, even though I do not specify FB property at all?

Deflagrate answered 5/6, 2019 at 9:38 Comment(2)
Do you use modules ? The answer differs a bit depeding on thatKetty
I use React components. All the behavior above is from React components. They may be called sort of modules because they incapsulate logicDeflagrate
K
488

Why does declare const window: any; work?

Because you declare a local variable of type any. Having something of type any essentially turns off type checking for window so you can do anything with it. I really do not recommend this solution, it is a really bad one.

Why doesn't type Window = { FB: any } work? You define a type Window. This type if defined in a module has nothing to do with the type of the global window object, it is just a type that happens to be called Window inside your module.

The good solution To extend window you must extend the global Window interface. You can do this like this:

declare global {
    interface Window {
        FB:any;
    }
}

let FB = window.FB; // ok now

Note that this extension is going to be available in your whole project not just the file you define it in. Also if FB has definitions you might consider typing it a bit better (FB: typeof import('FBOrWhateverModuleNameThisHas'))

Ketty answered 5/6, 2019 at 9:47 Comment(12)
Your "good solution" doesn't compile."Property FB does not exist on type window & typeof globalThis"Profiteer
@Profiteer yes it does typescriptlang.org/play?noImplicitReturns=false#code/… if your file is not a module, remove the declare global typescriptlang.org/play?noImplicitReturns=false#code/…Ketty
Why is this answer not marked as the Answer? I looked long and far to find a method to access reactive state functions from the console/external JS and this is the only one that compiled in TS and workedInsomnolence
@Insomnolence Because the OP couldn't get it to work and didn't bother to follow up 🤷‍♂️Ketty
If admins cared about the quality of the content on this site, they would take over this derelict question and accept an answer.Thetes
This doesn't work: Top-level declarations in .d.ts files must start with either a 'declare' or 'export' modifier.Bueno
If anyone is struggling with this answer on angular, put this code declare global { interface Window { FB:any; } } inside main.tsKerch
@Kerch Can anyone correct this codeArray
@VarunSharma is the same code of the answer, but without the let FB = window.FB partKerch
Putting it inside the main entry "main.ts" make it work, but why? why having it inside a global.d.ts doesn't work?Parse
ok, I figure it out, you need to put export {}; in the *.d.ts file in order for the compiler to read it.Parse
If anyone is doing this with Typescript, this link may help you. devextent.com/create-service-worker-typescriptMyrtlemyrvyn
E
88

There are a few ways to solve this problem.

Some examples:

1-) Do a cast

(window as any).X

2-) Put the following code in a file named react-app-env.d.ts

interface Window {
  X?: {
    Y?: {
      .......
    }
  }
}
Erythrocyte answered 7/9, 2021 at 2:49 Comment(2)
W̶i̶n̶d̶o̶w̶s̶ (window as any).XHype
In case of Vite - vite-env.d.ts fileWhatnot
S
32

you can solve the problem easily without any need to declaration

window["FB"]

UPDATE
since it's a workaround without any compiler configuration to ensure your program's compatibility with typescript maybe you will need just a type validation.

if(window["FB"]) {
  // do some FB logic
}
Spinach answered 13/10, 2021 at 4:46 Comment(5)
That didn't work, it says TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.Parse
@Parse this is the fastest way to solve the problem if you have specific type for index, you can use Titian's solutionSpinach
If you get the TS7015: Element implicitly has an 'any' type because index expression is not of type 'number' message, the following tsconfig.json property/value can be used to suppress it: "suppressImplicitAnyIndexErrors": trueMagdalenmagdalena
Don't suppress errors. The point of TypeScript is to catch errors like this.Ize
@Magdalenmagdalena You know the easiest way to suppress errors in Typescript is to use Javascript, right? If you're going to silence errors, why use Typescript? It's not like a truly static language where making the compile errors disappear is the same thing as fixing them. All you're doing is saying "I know better than you TS, shut up". But the whole reason for using Typescript is because most of us have learned, we usually don't know better than the compiler, at least not as the project grows or time passes on, and once you've silenced all the warnings, it's just JS or maybe even worse.Literature
J
16

I use this without declare global

declare const window: Window &
   typeof globalThis & {
     FB: any
   }
Jennie answered 26/7, 2021 at 13:0 Comment(2)
There is a bracket too much... removing it I get Cannot redeclare block-scoped variable 'window'Eboat
I did this too.Evaluate
F
16

Solution for the problem "Property does not exist on type Window in TypeScript":

STEP:1 In your src directory, create a types directory that contains the following index.d.ts file: src/types/index.d.ts

export {};

declare global {
  interface Window {
    example: string; // whatever type you want to give. (any,number,float etc)
  }
}

STEP: 2 add the path to your types directory to your tsconfig.json file.

tsconfig.json

{
  "compilerOptions": {
    // ... rest
    "typeRoots": ["./node_modules/@types", "./src/types"]
  }
}

STEP: 3 Now use it, whereever you want to do it.

window.example = 'hello';

console.log(window.example);
Fultz answered 5/8, 2022 at 13:47 Comment(2)
Why do you consider this a "HACK SOLUTION"?Froe
@Froe it works really well! i was messing around with so many things but this worked really well so i just said HACK SOLUTION because it resolved the problem. :)Fultz
A
10

I was facing this issue in my angular code. Below solution helped me to resolve the issue.

I resolved this error by creating a folder name types inside src and inside that folder created index.d.ts file.

the index.d.ts file will have below code.

export {};
declare global {
  interface Window {
    chrome: any;  // this will be your variable name
  }
}

If the error persists, try adding the path to your types directory to your tsconfig.json file.

{
  "compilerOptions": {
    // ... rest
    "typeRoots": ["./node_modules/@types", "./src/types"]
  }
}
Annelieseannelise answered 30/3, 2022 at 10:40 Comment(0)
U
7

it should be ignored by creating global.d.ts file in root of project with this content:

export { }
declare global {
    interface Window {
        [key: string]: any 
    }
}

it ignores all variables of window object

Unpolled answered 3/3, 2023 at 12:28 Comment(0)
H
5

better still

declare global {
  interface Window {
    FB: {
      CustomerChat: {
        hide: () => void;
        show: () => void;
      };
    };
  }
}
Hanhhank answered 13/10, 2021 at 6:11 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Tweak
O
3

This worked for me without declaring it globally

declare const window: Window &
   typeof globalThis & {
     FB: any
   }

This was the error I was facing Error: Property 'name' does not exist on type '{}'.ts(2339) Although mine wasn't really related with your code but this guide should help you

Ozoniferous answered 12/5, 2023 at 11:14 Comment(0)
R
0

For anyone coming from Next.Js, you need to use <Script /> inside of <body> to load it (loading it inside of the <Head /> won't work):

https://nextjs.org/docs/basic-features/script

Ruffian answered 11/10, 2022 at 18:10 Comment(0)
B
0

Use a temp variable and cast it to any

const tempWindow: any = window;
const anyProperty = tempWindow.anyProperty;
Baseball answered 20/8, 2023 at 8:7 Comment(0)
S
0

I've just added a Window interface in a file called global.d.ts inside the src directory in my react app like this:

interface Window {
  TOKEN: string;
}

The error is gone and I can assign the TOKEN variable like this without any issue:

window.TOKEN = process.env.TOKEN as string;
Sherrell answered 6/4 at 19:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.