@@ -33,42 +33,45 @@ declare global {
33
33
/**
34
34
* Converts property values to and from attribute values.
35
35
*/
36
- export interface ComplexAttributeConverter < Type = any , TypeHint = any > {
36
+ export interface ComplexAttributeConverter < Type = unknown , TypeHint = unknown > {
37
37
/**
38
38
* Function called to convert an attribute value to a property
39
39
* value.
40
40
*/
41
- fromAttribute ?( value : string , type ?: TypeHint ) : Type ;
41
+ fromAttribute ?( value : string | null , type ?: TypeHint ) : Type ;
42
42
43
43
/**
44
44
* Function called to convert a property value to an attribute
45
45
* value.
46
+ *
47
+ * It returns unknown instead of string, to be compatible with
48
+ * https://github.com/WICG/trusted-types (and similar efforts).
46
49
*/
47
- toAttribute ?( value : Type , type ?: TypeHint ) : string | null ;
50
+ toAttribute ?( value : Type , type ?: TypeHint ) : unknown ;
48
51
}
49
52
50
- type AttributeConverter < Type = any , TypeHint = any > =
53
+ type AttributeConverter < Type = unknown , TypeHint = unknown > =
51
54
ComplexAttributeConverter < Type > | ( ( value : string , type ?: TypeHint ) => Type ) ;
52
55
53
56
/**
54
57
* Defines options for a property accessor.
55
58
*/
56
- export interface PropertyDeclaration < Type = any , TypeHint = any > {
59
+ export interface PropertyDeclaration < Type = unknown , TypeHint = unknown > {
57
60
/**
58
61
* Indicates how and whether the property becomes an observed attribute.
59
62
* If the value is `false`, the property is not added to `observedAttributes`.
60
63
* If true or absent, the lowercased property name is observed (e.g. `fooBar`
61
64
* becomes `foobar`). If a string, the string value is observed (e.g
62
65
* `attribute: 'foo-bar'`).
63
66
*/
64
- attribute ?: boolean | string ;
67
+ readonly attribute ?: boolean | string ;
65
68
66
69
/**
67
70
* Indicates the type of the property. This is used only as a hint for the
68
71
* `converter` to determine how to convert the attribute
69
72
* to/from a property.
70
73
*/
71
- type ?: TypeHint ;
74
+ readonly type ?: TypeHint ;
72
75
73
76
/**
74
77
* Indicates how to convert the attribute to/from a property. If this value
@@ -82,7 +85,7 @@ export interface PropertyDeclaration<Type = any, TypeHint = any> {
82
85
* the property is never updated again as a result of the attribute changing,
83
86
* and vice versa.
84
87
*/
85
- converter ?: AttributeConverter < Type , TypeHint > ;
88
+ readonly converter ?: AttributeConverter < Type , TypeHint > ;
86
89
87
90
/**
88
91
* Indicates if the property should reflect to an attribute.
@@ -91,7 +94,7 @@ export interface PropertyDeclaration<Type = any, TypeHint = any> {
91
94
* property option and the value of the property converted using the rules
92
95
* from the `converter` property option.
93
96
*/
94
- reflect ?: boolean ;
97
+ readonly reflect ?: boolean ;
95
98
96
99
/**
97
100
* A function that indicates if a property should be considered changed when
@@ -108,7 +111,7 @@ export interface PropertyDeclaration<Type = any, TypeHint = any> {
108
111
* `this.requestUpdate(propertyName, oldValue)` to request an update when
109
112
* the property changes.
110
113
*/
111
- noAccessor ?: boolean ;
114
+ readonly noAccessor ?: boolean ;
112
115
}
113
116
114
117
/**
@@ -117,7 +120,7 @@ export interface PropertyDeclaration<Type = any, TypeHint = any> {
117
120
* PropertyDeclaration options.
118
121
*/
119
122
export interface PropertyDeclarations {
120
- [ key : string ] : PropertyDeclaration ;
123
+ readonly [ key : string ] : PropertyDeclaration ;
121
124
}
122
125
123
126
type PropertyDeclarationMap = Map < PropertyKey , PropertyDeclaration > ;
@@ -128,7 +131,7 @@ export type PropertyValues = Map<PropertyKey, unknown>;
128
131
129
132
export const defaultConverter : ComplexAttributeConverter = {
130
133
131
- toAttribute ( value : any , type ?: any ) {
134
+ toAttribute ( value : unknown , type ?: unknown ) : unknown {
132
135
switch ( type ) {
133
136
case Boolean :
134
137
return value ? '' : null ;
@@ -141,15 +144,15 @@ export const defaultConverter: ComplexAttributeConverter = {
141
144
return value ;
142
145
} ,
143
146
144
- fromAttribute ( value : any , type ?: any ) {
147
+ fromAttribute ( value : string | null , type ?: unknown ) {
145
148
switch ( type ) {
146
149
case Boolean :
147
150
return value !== null ;
148
151
case Number :
149
152
return value === null ? null : Number ( value ) ;
150
153
case Object :
151
154
case Array :
152
- return JSON . parse ( value ) ;
155
+ return JSON . parse ( value ! ) ;
153
156
}
154
157
return value ;
155
158
}
@@ -256,10 +259,12 @@ export abstract class UpdatingElement extends HTMLElement {
256
259
JSCompiler_renameProperty ( '_classProperties' , this ) ) ) {
257
260
this . _classProperties = new Map ( ) ;
258
261
// NOTE: Workaround IE11 not supporting Map constructor argument.
259
- const superProperties = Object . getPrototypeOf ( this ) . _classProperties ;
262
+ const superProperties : PropertyDeclarationMap =
263
+ Object . getPrototypeOf ( this ) . _classProperties ;
260
264
if ( superProperties !== undefined ) {
261
265
superProperties . forEach (
262
- ( v : any , k : PropertyKey ) => this . _classProperties ! . set ( k , v ) ) ;
266
+ ( v : PropertyDeclaration , k : PropertyKey ) =>
267
+ this . _classProperties ! . set ( k , v ) ) ;
263
268
}
264
269
}
265
270
}
@@ -289,11 +294,15 @@ export abstract class UpdatingElement extends HTMLElement {
289
294
}
290
295
const key = typeof name === 'symbol' ? Symbol ( ) : `__${ name } ` ;
291
296
Object . defineProperty ( this . prototype , name , {
297
+ // tslint:disable-next-line:no-any no symbol in index
292
298
get ( ) : any {
299
+ // tslint:disable-next-line:no-any no symbol in index
293
300
return ( this as any ) [ key ] ;
294
301
} ,
295
- set ( this : UpdatingElement , value : any ) {
302
+ set ( this : UpdatingElement , value : unknown ) {
303
+ // tslint:disable-next-line:no-any no symbol in index
296
304
const oldValue = ( this as any ) [ name ] ;
305
+ // tslint:disable-next-line:no-any no symbol in index
297
306
( this as any ) [ key ] = value ;
298
307
this . requestUpdate ( name , oldValue ) ;
299
308
} ,
@@ -338,6 +347,7 @@ export abstract class UpdatingElement extends HTMLElement {
338
347
for ( const p of propKeys ) {
339
348
// note, use of `any` is due to TypeSript lack of support for symbol in
340
349
// index types
350
+ // tslint:disable-next-line:no-any no symbol in index
341
351
this . createProperty ( p , ( props as any ) [ p ] ) ;
342
352
}
343
353
}
@@ -375,7 +385,7 @@ export abstract class UpdatingElement extends HTMLElement {
375
385
* @nocollapse
376
386
*/
377
387
private static _propertyValueFromAttribute (
378
- value : string , options : PropertyDeclaration ) {
388
+ value : string | null , options : PropertyDeclaration ) {
379
389
const type = options . type ;
380
390
const converter = options . converter || defaultConverter ;
381
391
const fromAttribute =
@@ -468,6 +478,7 @@ export abstract class UpdatingElement extends HTMLElement {
468
478
private _applyInstanceProperties ( ) {
469
479
// Use forEach so this works even if for/of loops are compiled to for loops
470
480
// expecting arrays
481
+ // tslint:disable-next-line:no-any
471
482
this . _instanceProperties ! . forEach ( ( v , p ) => ( this as any ) [ p ] = v ) ;
472
483
this . _instanceProperties = undefined ;
473
484
}
@@ -497,7 +508,7 @@ export abstract class UpdatingElement extends HTMLElement {
497
508
/**
498
509
* Synchronizes property values when attributes change.
499
510
*/
500
- attributeChangedCallback ( name : string , old : string , value : string ) {
511
+ attributeChangedCallback ( name : string , old : string | null , value : string | null ) {
501
512
if ( old !== value ) {
502
513
this . _attributeToProperty ( name , value ) ;
503
514
}
@@ -526,14 +537,14 @@ export abstract class UpdatingElement extends HTMLElement {
526
537
if ( attrValue == null ) {
527
538
this . removeAttribute ( attr ) ;
528
539
} else {
529
- this . setAttribute ( attr , attrValue ) ;
540
+ this . setAttribute ( attr , attrValue as string ) ;
530
541
}
531
542
// mark state not reflecting
532
543
this . _updateState = this . _updateState & ~ STATE_IS_REFLECTING_TO_ATTRIBUTE ;
533
544
}
534
545
}
535
546
536
- private _attributeToProperty ( name : string , value : string ) {
547
+ private _attributeToProperty ( name : string , value : string | null ) {
537
548
// Use tracking info to avoid deserializing attribute value if it was
538
549
// just set from a property setter.
539
550
if ( this . _updateState & STATE_IS_REFLECTING_TO_ATTRIBUTE ) {
@@ -547,7 +558,8 @@ export abstract class UpdatingElement extends HTMLElement {
547
558
// mark state reflecting
548
559
this . _updateState = this . _updateState | STATE_IS_REFLECTING_TO_PROPERTY ;
549
560
this [ propName as keyof this] =
550
- ctor . _propertyValueFromAttribute ( value , options ) ;
561
+ // tslint:disable-next-line:no-any
562
+ ctor . _propertyValueFromAttribute ( value , options ) as any ;
551
563
// mark state not reflecting
552
564
this . _updateState = this . _updateState & ~ STATE_IS_REFLECTING_TO_PROPERTY ;
553
565
}
@@ -566,7 +578,7 @@ export abstract class UpdatingElement extends HTMLElement {
566
578
* @param oldValue {any} (optional) old value of requesting property
567
579
* @returns {Promise } A Promise that is resolved when the update completes.
568
580
*/
569
- requestUpdate ( name ?: PropertyKey , oldValue ?: any ) {
581
+ requestUpdate ( name ?: PropertyKey , oldValue ?: unknown ) {
570
582
let shouldRequestUpdate = true ;
571
583
// if we have a property key, perform property update steps.
572
584
if ( name !== undefined && ! this . _changedProperties . has ( name ) ) {
0 commit comments