I created my Polymer element as following with TypeScript:
/// <reference path="./bower_components/polymer/types/polymer-element.d.ts"/>
class MyElement extends Polymer.Element {
static get is() {
return 'my-element';
}
static get properties() {
return {};
}
}
And I added a callback method to be notified the attribute changes:
attributeChangedCallback(name: string, oldVal: string | null, newVal: string | null) {
super.attributeChangedCallback(name, oldVal, newVal);
}
But tsc compiler raised an error as following:
index.ts:13:15 - error TS2339: Property 'attributeChangedCallback' does not exist on type 'Element'.
If my understanding about the Polymer elements' lifecycle is correct, a callback method in super instance must be called to handle lifecycle hooks properly. But tsc raises an error for it.
https://www.polymer-project.org/2.0/docs/devguide/custom-elements
https://github.com/rhysd/typescript-polymer-bug
$ git clone https://github.com/rhysd/typescript-polymer-bug.git
$ cd typescript-polymer-bug$ npm startCompilation is successfully done
Compilation error:
index.ts:13:15 - error TS2339: Property 'attributeChangedCallback' does not exist on type 'Element'.
13 super.attributeChangedCallback(name, oldVal, newVal);
~~~~~~~~~~~~~~~~~~~~~~~~
Hm it is defined in the properties-changed mixin (https://github.com/Polymer/polymer/blob/82cd3dad8d888fc375b433954c288fecfcaba0e9/types/lib/mixins/properties-changed.d.ts#L216-L224) which PropertyAccessors extends (https://github.com/Polymer/polymer/blob/82cd3dad8d888fc375b433954c288fecfcaba0e9/types/lib/mixins/property-accessors.d.ts#L35) which PropertyEffects extends (https://github.com/Polymer/polymer/blob/82cd3dad8d888fc375b433954c288fecfcaba0e9/types/lib/mixins/property-effects.d.ts#L49) which should then end up in Polymer.Element via https://github.com/Polymer/polymer/blob/82cd3dad8d888fc375b433954c288fecfcaba0e9/types/lib/mixins/element-mixin.d.ts#L79
I am not sure why this chain does not end up in your project. We probably have to update our own types to figure out where it is missing out on this property.
Yeah, I could find the constructor chain in my local directory also. And other callbacks such as connectedCallback are callbale.
Actually, all methods defined in property-changed.d.ts are not compiling. This might be a TypeScript bug, as I can't spot anything different with this file compared to the other files we define. @aomarks do you maybe know why this file is not properly being picked up by TypeScript?
I see what's going on. The mixin declarations we generate are defined as a function that returns a constructor for 1) the passed base class 2) that mixin's interface and 3) additional mixins that get automatically applied as picked up by analyzer using the @appliesMixin annotation.
The problem is that those mixins from 3) that are applied transitively are not automatically lifted up. So unless the @appliesMixin annotation is manually added at the top level, any mixin that is applied transitively is not declared.
In the ElementMixin case, the tree looks like this:
- ElementMixin
- PropertyEffects
- TemplateStamp
- PropertyAccessors
- PropertiesChanged
- Properties
- PropertiesChanged
Which means Polymer.Element will correctly extend ElementMixin and its direct @appliesMixins: PropertyEffects, and Properties. But the transitive ones TemplateStamp, PropertyAccessors, and PropertiesChanged are not declared.
Options:
1) Manually add @appliesMixin annotations to ElementMixin.
2) Update Analyzer to traverse the @appliesMixin tree and flatten it out.
3) Update the TypeScript generator to do 2).
I definitely think we should not do option 1, and should do either option 2 or 3. I suspect that option 3 is the better one, because it seems like it might be better able to handle stuff like DeduplicatingMixin, but if @justinfagnani has thoughts on that I'd defer to him here.
3 sounds good to me. The analyzer returns sufficient information - it could certainly flatten as a convenience, but it's not necessary.
Most helpful comment
I definitely think we should not do option 1, and should do either option 2 or 3. I suspect that option 3 is the better one, because it seems like it might be better able to handle stuff like
DeduplicatingMixin, but if @justinfagnani has thoughts on that I'd defer to him here.