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://stackoverflow.com/a/56402425/1114926
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?
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')
)
There are a few ways to solve this problem:
Somethings exemples:
1-) Do it a cast:
(window as any).X
2-) Put the follow code in file react-app-env.d.ts
interface Window {
X?: {
Y?: {
.......
}
}
}
you can solve the problem easily without any need to declaration
window["FB"]
I use this without declare global
declare const window: Window &
typeof globalThis & {
FB: any
}
Cannot redeclare block-scoped variable 'window'
better still
declare global {
interface Window {
FB: {
CustomerChat: {
hide: () => void;
show: () => void;
};
};
}
}
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"]
}
}
Success story sharing