-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expose global declarations on window
#19816
Expose global declarations on window
#19816
Comments
window
window
Can I bring up a third option? I think option 1 is the more flexible way of reducing duplicate declarations. However both options 1 & 2 have limitations:
A third option would be a declaration that tells the compiler to augment the global environment with all the declarations in a particular interface. Eg This is similar to option 1 but in reverse, and allows additional scenarios like sandboxing. An example of this scenario is given in #10050 (comment). Note that if option 1 was used, then there would be no way to write a set of declarations that are just a normal interface in the host code but are are globals in the sandboxed code. They would all still have to be duplicated. Custom environments may be niche, but it would be nice if the mechanism chosen here would work for them too. |
TypeScript team is figuring out how to expose these types on their `Window` interface, which `DOMWindow` extends (discussion [here](microsoft/TypeScript#19816)). In the meantime, this workaround will ensure that jsdom code compiles. Some types are not defined even globally by TypeScript. These have been commented out in the `DOMWindow` interface, but are still valid properties in jsdom. If someone tries to use these properties, their code will still not compile.
TypeScript team is figuring out how to expose these types on their `Window` interface, which `DOMWindow` extends (discussion [here](microsoft/TypeScript#19816)). In the meantime, this workaround will ensure that jsdom code compiles. Some types are not defined even globally by TypeScript. These have been commented out in the `DOMWindow` interface, but are still valid properties in jsdom. If someone tries to use these properties, their code will still not compile.
|
One other valid usecase is if you are working with different contexts. For example we could be in another DOM (inside an if ((myElement instanceof (myElement.ownerDocument.defaultView as any).SVGElement)) {
// yeah, really a svg
} |
I just hit on this when I tried to migrate js library that uses a lot of I though that it should be fixed in TS 3.4 after #29332 |
@mpawelski Yes, by 3.5. I just haven't had a chance yet. |
What is the status on this? |
Hey guys, so eventually, how nowadays with "typescript": "3.4.5" I can declare that inside window object, I have some variable with some type? E.g. I have window.foo = { bar: 'baz' }, how I can declare it? Old way of doing that, I mean declare global {
interface Window {
foo: { bar: string }
}
} is now produces this error
UPD: it looks like just adding a record in some d.ts file is ok. Like this: interface Window {
foo: { bar: string }
} But as I understood in such case I can't import some types in that file and use them in declaration, instead of import { MyTypeFromSomewhere } from './somewhere.d.ts'
interface Window {
foo: { bar: MyTypeFromSomewhere }
} ? |
@alendorff just to clarify: you had TS2669… error inside global.d.ts or index.d.ts? |
@inoyakaigor sorry, didn't understand your question, what's the difference between these 2 files if both are .d.ts ? I've not mentioned any specific filenames or something like that. |
@alendorff I had the same TS2669 error for the code inside global.d.ts and I'm trying to figure out if the file name is relevant to this error. That's why I'm asking about the file name |
@inoyakaigor I don't have global.d.ts so filename is irrelevant I think |
For anyone else landing here from a search, the following works to define new things on export {};
declare global {
interface Window {
// your types here!
}
} |
I want the dynamic key in window object. How can I do this? For example Can I do this?
|
In a Electron-React-Typescript app I'm getting this error: But in a file index.d.ts I declared interface Window in this way:
What should I add / modify in order to avoid this error
|
@raphael10-collab I don't think you need the |
I tried also without NodeJS : index.d.ts :
but still get this error:
in /src/App.tsx :
|
@raphael10-collab you have a typo: "api", { needs to be... "api": { Also, I'm not sure you can implement code in a You should have a separate file that does something like this... window.api = {
send: (channel, data) => {
ipcRenderer.invoke(channel, data).catch(e => console.log(e))
},
// etc.
} |
After removing that typo: "api", { --------> "api": { So, may be it is like you say, that I have to define window.api = {} in a separate file. I tried to put it into main.ts :
But still this error: |
You will need to put it in a file and then import that file into your application somewhere (the best spot may be in your main application file, something like // window.ts
window.api = {
// your code here
}
// app.tsx
import './window'; You will also still need the export {}; // needed to make TypeScript happy
declare global {
interface Window {
api: {
send: (channel: string, data: any) => void;
receive: (channel: string, func: () => void) => void;
// etc.
}
}
} |
I created two files:
window.ts :
And imported window.ts in main.ts and in src/components/App.tsx because of Electron apps added complexity of having two processes: main process and the renderer process. The number of errors is now half: from 15 to 8.
Found 8 errors. I've put all the code in github repo, easier to look at : https://github.com/raphael10-collab/Libp2pPlaying |
@raphael10-collab I opened a PR against your repo, I hope it is helpful! |
Thank you very much @TranquilMarmot There were and, unfortunately, there are a lot of errors. I still have the same "Property 'api' does not exist on type 'Window & typeof globalThis'.
68 ipcRenderer.removeAllListeners(channel);
|
It works for me using the code I have in my PR against your branch. You might have better luck asking about something like this on Stack overflow! Good luck! |
Window in a web page serves a dual purpose. it implements the
Window
interface representing the web page main view, but also acts as an alias to the global namespace. All global variables are accessible on thewindow
object at run-time; this applies to builtin JS declarations likeArray
,Math
,JSON
,Intl
as well as global DOM declarations likeHTMLElement
,Event
,HTMLCollection
, etc...TypeScript today does not model this behavior. For instance
window.Math
is not defined, so is all theHTMLElement
family of declarations.Most of the patterns
window
is used to access global declarations are anti-patterns (see a good article about window usage), the main exception is testing for API existence, e.g.:if (window.MutationObserver) { ... }
. There is not really a legal way to do this out-of-the-box in TS today.Our recommendation has been to manually add a declaration for the global object on
Window
, e.g.:This is a. inconvenient and b. not easy to find if you are new to TS. Here is a list of issues we have so far related to this issue:
window.Blob
window.createImageBitmap
window.Math
window.URL
window.MutationObserver
window.PointerEvent
window.MouseEvent
window.Element
window.PerformanceObserver
It is also worth noting that the same problem occurs with
self
in web workers andglobal
for nodePossible options here:
global
as a type #14052), and allowWindow
to extend from it.Window
.The text was updated successfully, but these errors were encountered: