From 93b41bf7f99b2a2507e15a6465bc157d6ff78c40 Mon Sep 17 00:00:00 2001 From: Steven Orvell Date: Mon, 16 Mar 2020 18:18:36 -0700 Subject: [PATCH] Removes index signature from PropertyDeclaration Fixes #928. Also add tests that type custom property options in a variety of ways. --- src/lib/updating-element.ts | 3 --- src/test/lib/updating-element_test.ts | 36 +++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/lib/updating-element.ts b/src/lib/updating-element.ts index 50dedcea..376cb619 100644 --- a/src/lib/updating-element.ts +++ b/src/lib/updating-element.ts @@ -113,9 +113,6 @@ export interface PropertyDeclaration { */ readonly noAccessor?: boolean; - // Allows extension while preserving the ability to use the - // @property decorator. - [index: string]: unknown; } /** diff --git a/src/test/lib/updating-element_test.ts b/src/test/lib/updating-element_test.ts index 50258747..e7cb3022 100644 --- a/src/test/lib/updating-element_test.ts +++ b/src/test/lib/updating-element_test.ts @@ -1868,6 +1868,12 @@ suite('UpdatingElement', () => { observer?: (oldValue: TypeHint) => void; } + interface MyPropertyDeclarations { + readonly [key: string]: PropertyDeclaration|MyPropertyDeclaration; + } + + const myProperty = (options: MyPropertyDeclaration) => property(options); + @customElement(generateElementName()) class E extends UpdatingElement { @@ -1902,7 +1908,8 @@ suite('UpdatingElement', () => { }); } - @property({type: Number, validator: (value: number) => Math.min(10, Math.max(value, 0))}) + // provide custom deorator expecting extended type + @myProperty({type: Number, validator: (value: number) => Math.min(10, Math.max(value, 0))}) foo = 5; @property({}) @@ -1911,23 +1918,48 @@ suite('UpdatingElement', () => { // tslint:disable-next-line:no-any _observedZot?: any; - @property({observer: function(this: E, oldValue: string) { this._observedZot = {value: this.zot, oldValue}; } }) + // tslint:disable-next-line:no-any + _observedZot2?: any; + + // use regular decorator and cast to type + @property({observer: function(this: E, oldValue: string) { this._observedZot = {value: this.zot, oldValue}; } } as PropertyDeclaration) zot = ''; + + zot2 = ''; + + foo2 = 5; + + // custom typed properties + static get properties(): MyPropertyDeclarations { + return { + // object cast as type + zot2: {observer: function(this: E, oldValue: string) { this._observedZot2 = {value: this.zot2, oldValue}; } } as PropertyDeclaration, + // object satisfying defined custom type. + foo2: {type: Number, validator: (value: number) => Math.min(10, Math.max(value, 0))} + }; + } } const el = new E(); container.appendChild(el); await el.updateComplete; el.foo = 20; + el.foo2 = 20; assert.equal(el.foo, 10); + assert.equal(el.foo2, 10); assert.deepEqual(el._observedZot, {value: '', oldValue: undefined}); + assert.deepEqual(el._observedZot2, {value: '', oldValue: undefined}); el.foo = -5; + el.foo2 = -5; assert.equal(el.foo, 0); + assert.equal(el.foo2, 0); el.bar = 'bar2'; assert.equal(el.bar, 'bar2'); el.zot = 'zot'; + el.zot2 = 'zot'; await el.updateComplete; assert.deepEqual(el._observedZot, {value: 'zot', oldValue: ''}); + assert.deepEqual(el._observedZot2, {value: 'zot', oldValue: ''}); }); test('attribute-based property storage', async () => {