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

Add ugly type assertions for this #659

Merged
merged 4 commits into from
Apr 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions src/lib/css-tag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const unsafeCSS = (value: unknown) => {
return new CSSResult(String(value), constructionToken);
};

const textFromCSSResult = (value: CSSResult | number) => {
const textFromCSSResult = (value: CSSResult|number) => {
if (value instanceof CSSResult) {
return value.cssText;
} else if (typeof value === 'number') {
Expand All @@ -79,9 +79,10 @@ const textFromCSSResult = (value: CSSResult | number) => {
* used. To incorporate non-literal values `unsafeCSS` may be used inside a
* template string part.
*/
export const css = (strings: TemplateStringsArray, ...values: (CSSResult | number)[]) => {
const cssText = values.reduce(
(acc, v, idx) => acc + textFromCSSResult(v) + strings[idx + 1],
strings[0]);
return new CSSResult(cssText, constructionToken);
};
export const css =
(strings: TemplateStringsArray, ...values: (CSSResult|number)[]) => {
const cssText = values.reduce(
(acc, v, idx) => acc + textFromCSSResult(v) + strings[idx + 1],
strings[0]);
return new CSSResult(cssText, constructionToken);
};
5 changes: 2 additions & 3 deletions src/lib/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,9 @@ const standardProperty =
// initializer: descriptor.initializer,
// }
// ],
// tslint:disable-next-line:no-any decorator
initializer(this: any) {
initializer(this: {[key: string]: unknown}) {
if (typeof element.initializer === 'function') {
this[element.key] = element.initializer.call(this);
this[element.key as string] = element.initializer.call(this);
}
},
finisher(clazz: typeof UpdatingElement) {
Expand Down
73 changes: 40 additions & 33 deletions src/lib/updating-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,14 +233,15 @@ export abstract class UpdatingElement extends HTMLElement {
*/
static get observedAttributes() {
// note: piggy backing on this to ensure we're finalized.
this.finalize();
(this as typeof UpdatingElement).finalize();
const attributes: string[] = [];
// Use forEach so this works even if for/of loops are compiled to for loops
// expecting arrays
this._classProperties!.forEach((v, p) => {
const attr = this._attributeNameForProperty(p, v);
(this as typeof UpdatingElement)._classProperties!.forEach((v, p) => {
const attr =
(this as typeof UpdatingElement)._attributeNameForProperty(p, v);
if (attr !== undefined) {
this._attributeToPropertyMap.set(attr, p);
(this as typeof UpdatingElement)._attributeToPropertyMap.set(attr, p);
attributes.push(attr);
}
});
Expand All @@ -255,16 +256,18 @@ export abstract class UpdatingElement extends HTMLElement {
/** @nocollapse */
private static _ensureClassProperties() {
// ensure private storage for property declarations.
if (!this.hasOwnProperty(
JSCompiler_renameProperty('_classProperties', this))) {
this._classProperties = new Map();
if (!(this as typeof UpdatingElement)
.hasOwnProperty(JSCompiler_renameProperty(
'_classProperties', (this as typeof UpdatingElement)))) {
(this as typeof UpdatingElement)._classProperties = new Map();
// NOTE: Workaround IE11 not supporting Map constructor argument.
const superProperties: PropertyDeclarationMap =
Object.getPrototypeOf(this)._classProperties;
Object.getPrototypeOf((this as typeof UpdatingElement))
._classProperties;
if (superProperties !== undefined) {
superProperties.forEach(
(v: PropertyDeclaration, k: PropertyKey) =>
this._classProperties!.set(k, v));
(this as typeof UpdatingElement)._classProperties!.set(k, v));
}
}
}
Expand All @@ -282,28 +285,27 @@ export abstract class UpdatingElement extends HTMLElement {
// Note, since this can be called by the `@property` decorator which
// is called before `finalize`, we ensure storage exists for property
// metadata.
this._ensureClassProperties();
this._classProperties!.set(name, options);
(this as typeof UpdatingElement)._ensureClassProperties();
(this as typeof UpdatingElement)._classProperties!.set(name, options);
// Do not generate an accessor if the prototype already has one, since
// it would be lost otherwise and that would never be the user's intention;
// Instead, we expect users to call `requestUpdate` themselves from
// user-defined accessors. Note that if the super has an accessor we will
// still overwrite it
if (options.noAccessor || this.prototype.hasOwnProperty(name)) {
if (options.noAccessor ||
(this as typeof UpdatingElement).prototype.hasOwnProperty(name)) {
return;
}
const key = typeof name === 'symbol' ? Symbol() : `__${name}`;
Object.defineProperty(this.prototype, name, {
Object.defineProperty((this as typeof UpdatingElement).prototype, name, {
// tslint:disable-next-line:no-any no symbol in index
get(): any {
return this[key];
return (this as {[key: string]: unknown})[key as string];
},
set(this: UpdatingElement, value: unknown) {
// tslint:disable-next-line:no-any no symbol in index
const oldValue = (this as any)[name];
// tslint:disable-next-line:no-any no symbol in index
(this as any)[key] = value;
this._requestUpdate(name, oldValue);
const oldValue = (this as {[key: string]: unknown})[name as string];
(this as {[key: string]: unknown})[key as string] = value;
(this as UpdatingElement)._requestUpdate(name, oldValue);
},
configurable: true,
enumerable: true
Expand All @@ -316,25 +318,29 @@ export abstract class UpdatingElement extends HTMLElement {
* @nocollapse
*/
protected static finalize() {
if (this.hasOwnProperty(JSCompiler_renameProperty('finalized', this)) &&
this.finalized) {
if ((this as typeof UpdatingElement)
.hasOwnProperty(JSCompiler_renameProperty(
'finalized', (this as typeof UpdatingElement))) &&
(this as typeof UpdatingElement).finalized) {
return;
}
// finalize any superclasses
const superCtor = Object.getPrototypeOf(this);
const superCtor = Object.getPrototypeOf((this as typeof UpdatingElement));
if (typeof superCtor.finalize === 'function') {
superCtor.finalize();
}
this.finalized = true;
this._ensureClassProperties();
(this as typeof UpdatingElement).finalized = true;
(this as typeof UpdatingElement)._ensureClassProperties();
// initialize Map populated in observedAttributes
this._attributeToPropertyMap = new Map();
(this as typeof UpdatingElement)._attributeToPropertyMap = new Map();
// make any properties
// Note, only process "own" properties since this element will inherit
// any properties defined on the superClass, and finalization ensures
// the entire prototype chain is finalized.
if (this.hasOwnProperty(JSCompiler_renameProperty('properties', this))) {
const props = this.properties;
if ((this as typeof UpdatingElement)
.hasOwnProperty(JSCompiler_renameProperty(
'properties', (this as typeof UpdatingElement)))) {
const props = (this as typeof UpdatingElement).properties;
// support symbols in properties (IE11 does not support this)
const propKeys = [
...Object.getOwnPropertyNames(props),
Expand All @@ -347,7 +353,7 @@ export abstract class UpdatingElement extends HTMLElement {
// note, use of `any` is due to TypeSript lack of support for symbol in
// index types
// tslint:disable-next-line:no-any no symbol in index
this.createProperty(p, (props as any)[p]);
(this as typeof UpdatingElement).createProperty(p, (props as any)[p]);
}
}
}
Expand Down Expand Up @@ -441,7 +447,8 @@ export abstract class UpdatingElement extends HTMLElement {
*/
protected initialize() {
this._saveInstanceProperties();
// ensures first update will be caught by an early access of `updateComplete`
// ensures first update will be caught by an early access of
// `updateComplete`
this._requestUpdate();
}

Expand Down Expand Up @@ -486,10 +493,10 @@ export abstract class UpdatingElement extends HTMLElement {

connectedCallback() {
this._updateState = this._updateState | STATE_HAS_CONNECTED;
// Ensure first connection completes an update. Updates cannot complete before
// connection and if one is pending connection the `_hasConnectionResolver`
// will exist. If so, resolve it to complete the update, otherwise
// requestUpdate.
// Ensure first connection completes an update. Updates cannot complete
// before connection and if one is pending connection the
// `_hasConnectionResolver` will exist. If so, resolve it to complete the
// update, otherwise requestUpdate.
if (this._hasConnectedResolver) {
this._hasConnectedResolver();
this._hasConnectedResolver = undefined;
Expand Down
12 changes: 7 additions & 5 deletions src/lit-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,12 @@ export class LitElement extends UpdatingElement {
super.finalize();
// Prepare styling that is stamped at first render time. Styling
// is built from user provided `styles` or is inherited from the superclass.
this._styles =
this.hasOwnProperty(JSCompiler_renameProperty('styles', this)) ?
this._getUniqueStyles() :
this._styles || [];
(this as typeof LitElement)._styles =
(this as typeof LitElement)
.hasOwnProperty(JSCompiler_renameProperty(
'styles', (this as typeof LitElement))) ?
(this as typeof LitElement)._getUniqueStyles() :
(this as typeof LitElement)._styles || [];
}

/** @nocollapse */
Expand All @@ -102,7 +104,7 @@ export class LitElement extends UpdatingElement {
// shared styles will generate new stylesheet objects, which is wasteful.
// This should be addressed when a browser ships constructable
// stylesheets.
const userStyles = this.styles;
const userStyles = (this as typeof LitElement).styles;
const styles: CSSResult[] = [];
if (Array.isArray(userStyles)) {
const flatStyles = flattenStyles(userStyles);
Expand Down
Loading