Skip to content
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

getElementById inconsistent between TS and Closure #163

Closed
evmar opened this issue Jun 15, 2016 · 6 comments
Closed

getElementById inconsistent between TS and Closure #163

evmar opened this issue Jun 15, 2016 · 6 comments

Comments

@evmar
Copy link
Contributor

evmar commented Jun 15, 2016

document.getElementById returns an Element in Closure and an HTMLElement in TS. (Element is the supertype; SVG elements are a sibling to HTML elements.) This leads to compilation problems like:

WARNING - initializing variable
found   : (Element|null)
required: (HTMLElement|null)
    let /** @type {HTMLElement} */ outputEl = document.getElementById('output');

microsoft/TypeScript#3263 (comment) says: "However, in the case of getElementById, we made it convenient by returning HTMLElement by default, although it is different from the spec." Sadness.

It looks like they might change something in this area in microsoft/TypeScript#4689 .

See also #42 . This is maybe an argument for using our own modified standard library.

@evmar
Copy link
Contributor Author

evmar commented Jun 15, 2016

To repro this in a test:

let foo = document.getElementById('foo');

it produces

let /** @type {HTMLElement} */ foo = document.getElementById('foo');

@evmar
Copy link
Contributor Author

evmar commented Jun 15, 2016

Note that you can't work around this with coercions because of bugs like microsoft/TypeScript#6982 where comments are dropped.

let foo = <Element>document.getElementById('foo');

becomes

let /** @type {Element} */ foo = /** @type {Element} */(( <Element>document.getElementById('foo')));

becomes

let /** @type {Element} */ foo = (document.getElementById('foo'));

And see that "Element" was dropped.

@mprobst
Copy link
Contributor

mprobst commented Jun 15, 2016 via email

@evmar
Copy link
Contributor Author

evmar commented Jun 15, 2016

In theory we're relying on types for optimization, so I'm not sure what it means if we disable type checking. Like if you write

let foo = document.getElementById('foo');
foo.barField;

where "barField" is in HTMLElement but not Element, I'm not sure what the Closure optimizer will do to barField when it thinks it's not a valid field.

@mprobst
Copy link
Contributor

mprobst commented Jun 15, 2016

My unchecked understanding is that Closure Compiler will rename properties
that are never mentioned in externs, but at least without --disambiguate
options will just never rename a property that's mentioned anywhere in
your externs.

With it on, it's unclear, there's some stuff in Closure Compiler where it's
trying to be conservative if a sub or supertype defines a property.

@evmar
Copy link
Contributor Author

evmar commented Aug 20, 2019

We suppressed checkTypes.

@evmar evmar closed this as completed Aug 20, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants