@@ -46,6 +46,35 @@ export interface PropertyOptions {
46
46
observer ?: string | ( ( val : any , old : any ) => void ) ;
47
47
}
48
48
49
+ function createProperty ( proto : any , name : string , options ?: PropertyOptions ) : void {
50
+ const notify = options && options . notify || false ;
51
+ const reflectToAttribute = options && options . reflectToAttribute || false ;
52
+ const readOnly = options && options . readOnly || false ;
53
+ const computed = options && options . computed || '' ;
54
+ const observer = options && options . observer || '' ;
55
+
56
+ let type ;
57
+ if ( options && options . hasOwnProperty ( 'type' ) ) {
58
+ type = options . type ;
59
+ } else if (
60
+ ( window as any ) . Reflect && Reflect . hasMetadata && Reflect . getMetadata &&
61
+ Reflect . hasMetadata ( 'design:type' , proto , name ) ) {
62
+ type = Reflect . getMetadata ( 'design:type' , proto , name ) ;
63
+ } else {
64
+ console . error (
65
+ 'A type could not be found for ${propName}. ' +
66
+ 'Set a type or configure Metadata Reflection API support.' ) ;
67
+ }
68
+
69
+ if ( ! proto . constructor . hasOwnProperty ( 'properties' ) ) {
70
+ proto . constructor . properties = { } ;
71
+ }
72
+
73
+ const finalOpts : PropertyOptions =
74
+ { type, notify, reflectToAttribute, readOnly, computed, observer} ;
75
+ proto . constructor . properties [ name ] = finalOpts ;
76
+ }
77
+
49
78
/**
50
79
* A TypeScript property decorator factory that defines this as a Polymer
51
80
* property.
@@ -54,31 +83,7 @@ export interface PropertyOptions {
54
83
*/
55
84
export function property ( options ?: PropertyOptions ) {
56
85
return ( proto : any , propName : string ) : any => {
57
- const notify = options && options . notify || false ;
58
- const reflectToAttribute = options && options . reflectToAttribute || false ;
59
- const readOnly = options && options . readOnly || false ;
60
- const computed = options && options . computed || '' ;
61
- const observer = options && options . observer || '' ;
62
-
63
- let type ;
64
- if ( options && options . hasOwnProperty ( 'type' ) ) {
65
- type = options . type ;
66
- } else if (
67
- ( window as any ) . Reflect && Reflect . hasMetadata && Reflect . getMetadata &&
68
- Reflect . hasMetadata ( 'design:type' , proto , propName ) ) {
69
- type = Reflect . getMetadata ( 'design:type' , proto , propName ) ;
70
- } else {
71
- console . error (
72
- 'A type could not be found for ${propName}. ' +
73
- 'Set a type or configure Metadata Reflection API support.' ) ;
74
- }
75
-
76
- if ( ! proto . constructor . hasOwnProperty ( 'properties' ) ) {
77
- proto . constructor . properties = { } ;
78
- }
79
- const finalOpts : PropertyOptions =
80
- { type, notify, reflectToAttribute, readOnly, computed, observer} ;
81
- proto . constructor . properties [ propName ] = finalOpts ;
86
+ createProperty ( proto , propName , options ) ;
82
87
}
83
88
}
84
89
@@ -100,6 +105,31 @@ export function observe(targets: string|string[]) {
100
105
}
101
106
}
102
107
108
+ /**
109
+ * A TypeScript accessor decorator factory that causes the decorated getter to
110
+ * be called when a set of dependencies change. The arguments of this decorator
111
+ * should be paths of the data dependencies as described
112
+ * [here](https://www.polymer-project.org/2.0/docs/devguide/observers#define-a-computed-property)
113
+ * The decorated getter should not have an associated setter.
114
+ *
115
+ * This function must be invoked to return a decorator.
116
+ */
117
+ export function computed < T = any > ( ...targets : ( keyof T ) [ ] ) {
118
+ return ( proto : any , propName : string , descriptor : PropertyDescriptor ) : void => {
119
+ const fnName = `__compute${ propName } ` ;
120
+
121
+ Object . defineProperty ( proto , fnName , {
122
+ value : descriptor . get
123
+ } ) ;
124
+
125
+ descriptor . get = undefined ;
126
+
127
+ createProperty ( proto , propName , {
128
+ computed : `${ fnName } (${ targets . join ( ',' ) } )`
129
+ } ) ;
130
+ } ;
131
+ }
132
+
103
133
/**
104
134
* A TypeScript property decorator factory that converts a class property into
105
135
* a getter that executes a querySelector on the element's shadow root.
0 commit comments