You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm not entirely sure whether this one should be called a suggestion or a bug, due to the interactions it involves and how that might be related to TypeScript's design. Tested with 2.6.2 and 2.7.1.
Our problem can best be explained by examining the following two blocks of code first:
Code Set 1
var frame = document.getElementById('myFrame') as HTMLIFrameElement
var ele = frame.contentDocument.getElementById('input1') as HTMLInputElement;
// ...
if(ele instanceof HTMLInputElement) {
console.log('Yep, it\'s an HTMLInputElement.');
} else {
console.log('HTMLInputElement constructor mismatch!')
}
Expected behavior:
Console log: > Yep, it's an HTMLInputElement.
Actual behavior: > HTMLInputElement constructor mismatch!
The short version - any element within an HTMLIFrameElement's internal document is based upon a different constructor set, as the HTMLIFrameElement has its own Window instance (.contentWindow). In the general case, this is good JavaScript design that helps to isolate documents within an HTMLIFrameElement from the master document.
var ele = document.getElementById('input1') as HTMLInputElement
// ...
var proto = window.HTMLInputElement // Error is on this line.
if(ele instanceof proto) {
console.log('Yep, it\'s an HTMLInputElement.');
}
Expected behavior:
Console log: > Yep, it's an HTMLInputElement.
Actual behavior:
source.ts(__, __): error TS2339: Property 'HTMLInputElement' does not exist on type 'Window'
Never mind the fact that it actually does exist there in JavaScript on all the major browsers; TypeScript doesn't acknowledge that the base window object (or .defaultView/.contentWindow property Window object) contains the original class constructors for its corresponding Document.
Overall desired behavior:
At present, the above two issues combine to make the following impossible in plain TypeScript without losing type information to some degree:
var frame = document.getElementById('myFrame') as HTMLIFrameElement
var ele: HTMLElement = frame.contentDocument.getElementById('input1');
if(ele instanceof ele.ownerDocument.defaultView.HTMLInputElement) {
console.log("We have an instance of the IFrame's HTMLInputElement class!");
console.log("It's value: " + ele.value);
}
Even if, within our own codebase, we extend Window via interface to have a property HTMLInputElement: () => HTMLInputElement to model the constructor all Window instances possess, ele.value's line will return an error because it will require a manual cast, unlike with a plain ele instanceof HTMLInputElement... which fails here because HTMLInputElement will correspond to the constructor from the base window: Window. There's no way to do this at present that feels like 'proper' TypeScript.
The ideal scenario would thus be for the Window class to contain a readonly set of HTMLElement constructors (among others), which should allow for safe use of instanceof upon window.HTMLElement equivalent with that of upon top-level HTMLElement.
Never mind the fact that it actually does exist there in JavaScript on all the major browsers; TypeScript doesn't acknowledge that the base window object (or .defaultView/.contentWindow property Window object) contains the original class constructors for its corresponding Document.
Global declarations are intentionally elided from Window. you can always add them in your own code base by adding;
I'm not entirely sure whether this one should be called a suggestion or a bug, due to the interactions it involves and how that might be related to TypeScript's design. Tested with 2.6.2 and 2.7.1.
Our problem can best be explained by examining the following two blocks of code first:
Code Set 1
Expected behavior:
Console log:
> Yep, it's an HTMLInputElement.
Actual behavior:
> HTMLInputElement constructor mismatch!
The short version - any element within an
HTMLIFrameElement
's internal document is based upon a different constructor set, as theHTMLIFrameElement
has its ownWindow
instance (.contentWindow
). In the general case, this is good JavaScript design that helps to isolate documents within anHTMLIFrameElement
from the master document.Code Set 2
Expected behavior:
Console log:
> Yep, it's an HTMLInputElement.
Actual behavior:
source.ts(__, __): error TS2339: Property 'HTMLInputElement' does not exist on type 'Window'
Never mind the fact that it actually does exist there in JavaScript on all the major browsers; TypeScript doesn't acknowledge that the base
window
object (or.defaultView
/.contentWindow
propertyWindow
object) contains the original class constructors for its correspondingDocument
.Overall desired behavior:
At present, the above two issues combine to make the following impossible in plain TypeScript without losing type information to some degree:
Even if, within our own codebase, we extend
Window
via interface to have a propertyHTMLInputElement: () => HTMLInputElement
to model the constructor allWindow
instances possess,ele.value
's line will return an error because it will require a manual cast, unlike with a plainele instanceof HTMLInputElement
... which fails here becauseHTMLInputElement
will correspond to the constructor from the basewindow: Window
. There's no way to do this at present that feels like 'proper' TypeScript.The ideal scenario would thus be for the
Window
class to contain areadonly
set ofHTMLElement
constructors (among others), which should allow for safe use ofinstanceof
uponwindow.HTMLElement
equivalent with that of upon top-levelHTMLElement
.Search Terms:
iframe
instanceof
cross-frame
window
constructor
The text was updated successfully, but these errors were encountered: