-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Unable to extend window in TS 3.6 #33128
Comments
Perhaps unrelated, but I ran across this spectacularly weird error while trying to work around this: type T = Window & typeof globalThis;
interface MyWindow extends T {
foo: string;
} Error:
|
Augmentation of export {}
declare global {
interface Window {
foo: string;
}
}
window.foo = 'bar'; or interface Window {
foo: string;
}
window.foo = 'bar'; For non-module scenarios. |
The appeal of extending Window and using an assertion is that it's not global. Though I suppose if you're extending a global singleton, you don't have much ground to stand on! |
When using modules, the interface merge will be local to the file it occurs in, I believe. It's true you can't make the scope any narrower than that, but at least it won't poison outside code. |
Why not include (window as MyWindow & typeof globalThis).foo = 'bar'; This is indeed working as intended. As for the weird error, Window has a numeric index signature |
Thanks @sandersn. The missing piece was that |
Wait, what. The index signature |
@fatcerberus the property is named |
Oh I see, I didn’t realize those were covered by a numeric index signature because they’re not valid array indices. I know they are covered by |
@fatcerberus I don't believe this statement is correct:
I put this in a new file in my project ( export {};
declare global {
interface Document {
/** documentation on foo */
foo: string;
}
} Then, in another file, I can write: document.foo; without importing |
Typescript 3.6 causes an incompatibility in eslint (or at least the risk of it) which makes for quite verbose warnings. Cf. Ie0bfd9871384c4daf9a3d4a8e5801edcc0a27d5b Also some of the challenges seen in I65d50c908ca706105f7d5e5b709487df7c908621 (having to cast a window as any before being able to make it a MwWindow) go away on the lower version, which could be helpful until we follow the suggested mitigation[0]. [0] microsoft/TypeScript#33128 Change-Id: Ic6e13f75a71b0212f81ebacd16d344fc8ea875e4
* Update Wikibase from branch 'master' to 0f1c1752140e77f6c90fcc21271178a5d9bf9358 - Merge "tainted ref: don't use TS 3.6 just yet" - tainted ref: don't use TS 3.6 just yet Typescript 3.6 causes an incompatibility in eslint (or at least the risk of it) which makes for quite verbose warnings. Cf. Ie0bfd9871384c4daf9a3d4a8e5801edcc0a27d5b Also some of the challenges seen in I65d50c908ca706105f7d5e5b709487df7c908621 (having to cast a window as any before being able to make it a MwWindow) go away on the lower version, which could be helpful until we follow the suggested mitigation[0]. [0] microsoft/TypeScript#33128 Change-Id: Ic6e13f75a71b0212f81ebacd16d344fc8ea875e4
Apply latest TypeScript version[0] and fix resulting complaints. The question of how to extend window may be noteworthy[1] as the `declare global` in MwWindow does something profound but in a well-hidden spot. I guess this should be made more prominent, maybe in a @types/global.d.ts - acknowledging what's going on in practice. eslint warnings about incompatibility with latest TS, as seen earlier (b40683d), seem to no longer happen. Let's leave applying goodies (e.g. "Optional Chaining") for later to reduce the rebase effort for a dependent patch (I8dea58b3b4c40b265d86b28b63cc8d692ac7929c). [0] https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html [1] microsoft/TypeScript#33128 Change-Id: I0d7f6228276f60eb4b3866f470311f59aeef5d39
* Update Wikibase from branch 'master' to a5e6df0da5fa9b4cd9af63cb187a8477dc289775 - Merge "bridge: update to TypeScript 3.7" - bridge: update to TypeScript 3.7 Apply latest TypeScript version[0] and fix resulting complaints. The question of how to extend window may be noteworthy[1] as the `declare global` in MwWindow does something profound but in a well-hidden spot. I guess this should be made more prominent, maybe in a @types/global.d.ts - acknowledging what's going on in practice. eslint warnings about incompatibility with latest TS, as seen earlier (b40683d), seem to no longer happen. Let's leave applying goodies (e.g. "Optional Chaining") for later to reduce the rebase effort for a dependent patch (I8dea58b3b4c40b265d86b28b63cc8d692ac7929c). [0] https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html [1] microsoft/TypeScript#33128 Change-Id: I0d7f6228276f60eb4b3866f470311f59aeef5d39
quick and dirty 💥
|
Thx your answer, Im just curious whats the first line export {} for? |
To force the file to be registered as a module, not a script |
@orta Can I ask why it needs to be registered as a module? For me this doesn't work until the add the
|
@danvk wrote:
Super-late response here, but there exist some TypeScript wrappers that will treat this differently. In particular, at Google we redefine |
If you want the type augmentation to be global and ambient, this works fine:
The trick is, you must put this in a file with the extension |
The solution we recommend at Google is to make a local subtype for explicit casts, which avoids polluting the global type definitions. Because of the type GlobalThis = typeof globalThis & Window & {
NaN: never;
Infinity: never;
}; which can then be used like so: (playground) interface MyGlobal extends GlobalThis {
readonly foo: number;
}
use((window as MyGlobal).foo); |
@shicks Thanks for the tip! Makes sense. Some projects/packages are small enough and use of a global object pervasive enough that boosting a type to be globally ambient is useful (especially in packages that aren't consumed by other packages). But when polluting the global scope is harmful, this seems like a good technique to reduce the boilerplate and complexity of strongly typing at use-time. |
This is correct method for window type extend |
Is it possible to extend Window with |
TypeScript Version: 3.6.2
Search Terms:
Code
This code passed the type checker in TS 3.5:
but fails with this error in TS 3.6:
Following the release notes, I can work around the issue by changing from
interface
totype
and using an intersection:but this feels more obscure than the old way. Is this WAI? What's the rationale for the non-extendable Window?
Expected behavior:
An interface should be able to extend
Window
.Actual behavior:
The error above.
Playground Link: 3.6 isn't on the playground yet.
Related Issues:
The text was updated successfully, but these errors were encountered: