Green
Green

Reputation: 30805

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

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?

Upvotes: 301

Views: 366307

Answers (14)

Ben Racicot
Ben Racicot

Reputation: 5915

There's got to be a better way to get a properly types Window object in 2025...

export interface CSSMatrix {
  a: number;
  b: number;
  c: number;
  d: number;
  e: number;
  f: number;
  m11: number;
  m12: number;
  m13: number;
  m14: number;
  m21: number;
  m22: number;
  m23: number;
  m24: number;
  m31: number;
  m32: number;
  m33: number;
  m34: number;
  m41: number;
  m42: number;
  m43: number;
  m44: number;
}

declare global {
  interface Window {
    WebKitCSSMatrix?: CSSMatrix;
    MSCSSMatrix?: CSSMatrix;
    CSSMatrix?: CSSMatrix;
  }

  interface CSSStyleDeclaration {
    animatingX?: string;
    animatingY?: string;
  }
}

// This empty export makes this file a module
export {}

Upvotes: 0

hansss
hansss

Reputation: 521

Another way of bypassing index.d.ts file is to cast it with types.

Extending @Fábio answer, instead of:

(window as any).X

You could:

(window as Window & typeof globalThis & { x: string }).x

Works great if you are looking for a one-time solution without using any

Upvotes: 0

Mehdi Faraji
Mehdi Faraji

Reputation: 3826

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;

Upvotes: 0

Jamal Ashraf
Jamal Ashraf

Reputation: 935

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);

Upvotes: 25

KISHORE K J
KISHORE K J

Reputation: 615

Use a temp variable and cast it to any

const tempWindow: any = window;
const anyProperty = tempWindow.anyProperty;

Upvotes: 3

Justice
Justice

Reputation: 81

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

Upvotes: 3

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?: {
      .......
    }
  }
}

Upvotes: 101

Saeid Doroudi
Saeid Doroudi

Reputation: 1235

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

Upvotes: 10

S.Saderi
S.Saderi

Reputation: 5523

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
}

Upvotes: 32

a7dc
a7dc

Reputation: 3416

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

Upvotes: 0

Avadhut Lakule
Avadhut Lakule

Reputation: 119

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"]
  }
}

Upvotes: 11

Hugo Laguna
Hugo Laguna

Reputation: 202

I use this without declare global

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

Upvotes: 18

bitotm
bitotm

Reputation: 59

better still

declare global {
  interface Window {
    FB: {
      CustomerChat: {
        hide: () => void;
        show: () => void;
      };
    };
  }
}

Upvotes: 5

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249646

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'))

Upvotes: 518

Related Questions