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

后端 未结 23 2183
青春惊慌失措
青春惊慌失措 2020-11-22 03:53

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

window.MyNamespace = window.MyNamespace || {};
相关标签:
23条回答
  • 2020-11-22 04:32

    typescript prevent accessing object without assigning type that has the desired property or already assigned to any so you can use optional chaining window?.MyNamespace = 'value'.

    0 讨论(0)
  • 2020-11-22 04:35

    Most of the other answers are not perfect.

    • Some of them just suppress the type inference for shop.
    • Some of the others only cares about global variable as namespace, but not as interface/class

    I also encounter the similar problem this morning. I tried so many "solutions" on SO, but none of them produce no type error absolutely and enable triggering type jumping in IDE(webstorm or vscode).

    Finally, from here

    https://github.com/Microsoft/TypeScript/issues/3180#issuecomment-102523512

    , I find a reasonable solution to attach typings for global variable which acts as interface/class and namespace both.

    Example is below:

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

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

    0 讨论(0)
  • 2020-11-22 04:36

    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 <any> so you can do

    (window as any)[DynamicObject.key]
    
    0 讨论(0)
  • 2020-11-22 04:38

    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.

    0 讨论(0)
  • 2020-11-22 04:39

    First you need to declare the window object in current scope.
    Because typescript would like to know the type of the object.
    Since window object is defined somewhere else you can not redefine it.
    But you can declare it as follows:-

    declare var window: any;
    

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

    Then you can refer to your MyNamespace object simply by:-

    window.MyNamespace
    

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

    window.MyNamespace = MyObject
    

    And now the typescript won't complain.

    0 讨论(0)
提交回复
热议问题