@ckeditor/ckeditor5-utils 48.2.0-alpha.7 → 48.3.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/dist/abortabledebounce.d.ts +19 -13
  2. package/dist/areconnectedthroughproperties.d.ts +7 -7
  3. package/dist/ckeditorerror.d.ts +113 -113
  4. package/dist/collection.d.ts +419 -415
  5. package/dist/collectstylesheets.d.ts +9 -9
  6. package/dist/comparearrays.d.ts +25 -25
  7. package/dist/config.d.ts +159 -156
  8. package/dist/count.d.ts +14 -14
  9. package/dist/crc32.d.ts +19 -19
  10. package/dist/decodelicensekey.d.ts +7 -7
  11. package/dist/delay.d.ts +13 -13
  12. package/dist/diff.d.ts +32 -27
  13. package/dist/difftochanges.d.ts +47 -47
  14. package/dist/dom/createelement.d.ts +43 -43
  15. package/dist/dom/emittermixin.d.ts +144 -135
  16. package/dist/dom/findclosestscrollableancestor.d.ts +8 -8
  17. package/dist/dom/getancestors.d.ts +13 -13
  18. package/dist/dom/getborderwidths.d.ts +16 -16
  19. package/dist/dom/getcommonancestor.d.ts +9 -9
  20. package/dist/dom/getdatafromelement.d.ts +10 -10
  21. package/dist/dom/getpositionedancestor.d.ts +7 -7
  22. package/dist/dom/getrangefrommouseevent.d.ts +12 -12
  23. package/dist/dom/getvisualviewportoffset.d.ts +7 -7
  24. package/dist/dom/global.d.ts +24 -24
  25. package/dist/dom/indexof.d.ts +10 -10
  26. package/dist/dom/insertat.d.ts +11 -11
  27. package/dist/dom/iscomment.d.ts +7 -7
  28. package/dist/dom/isnode.d.ts +7 -7
  29. package/dist/dom/isrange.d.ts +7 -7
  30. package/dist/dom/istext.d.ts +7 -7
  31. package/dist/dom/isvalidattributename.d.ts +7 -7
  32. package/dist/dom/isvisible.d.ts +12 -12
  33. package/dist/dom/iswindow.d.ts +7 -7
  34. package/dist/dom/position.d.ts +200 -200
  35. package/dist/dom/rect.d.ts +194 -194
  36. package/dist/dom/remove.d.ts +9 -9
  37. package/dist/dom/resizeobserver.d.ts +70 -70
  38. package/dist/dom/scroll.d.ts +75 -72
  39. package/dist/dom/setdatainelement.d.ts +10 -10
  40. package/dist/dom/tounit.d.ts +16 -16
  41. package/dist/elementreplacer.d.ts +26 -26
  42. package/dist/emittermixin.d.ts +290 -280
  43. package/dist/env.d.ts +124 -124
  44. package/dist/eventinfo.d.ts +58 -55
  45. package/dist/fastdiff.d.ts +112 -109
  46. package/dist/first.d.ts +7 -7
  47. package/dist/focustracker.d.ts +133 -131
  48. package/dist/formathtml.d.ts +15 -15
  49. package/dist/index-content.css +1 -0
  50. package/dist/index-editor.css +1 -0
  51. package/dist/index.css +0 -2
  52. package/dist/index.d.ts +78 -77
  53. package/dist/index.js +5695 -6360
  54. package/dist/index.js.map +1 -1
  55. package/dist/inserttopriorityarray.d.ts +23 -23
  56. package/dist/isfeatureblockedbylicensekey.d.ts +10 -10
  57. package/dist/isiterable.d.ts +10 -10
  58. package/dist/keyboard.d.ts +107 -109
  59. package/dist/keystrokehandler.d.ts +90 -90
  60. package/dist/language.d.ts +12 -12
  61. package/dist/legacyerrors.d.ts +0 -4
  62. package/dist/locale.d.ts +122 -122
  63. package/dist/mapsequal.d.ts +11 -11
  64. package/dist/mix.d.ts +54 -53
  65. package/dist/nth.d.ts +12 -12
  66. package/dist/objecttomap.d.ts +18 -18
  67. package/dist/observablemixin.d.ts +621 -539
  68. package/dist/parsebase64encodedobject.d.ts +7 -7
  69. package/dist/parsedimensionwithunit.d.ts +40 -0
  70. package/dist/priorities.d.ts +24 -24
  71. package/dist/retry.d.ts +27 -27
  72. package/dist/splicearray.d.ts +22 -22
  73. package/dist/spy.d.ts +15 -15
  74. package/dist/toarray.d.ts +17 -17
  75. package/dist/tomap.d.ts +15 -15
  76. package/dist/translation-service.d.ts +157 -157
  77. package/dist/uid.d.ts +12 -12
  78. package/dist/unicode.d.ts +42 -42
  79. package/dist/version.d.ts +5 -5
  80. package/dist/wait.d.ts +11 -11
  81. package/package.json +2 -2
  82. package/dist/index.css.map +0 -1
@@ -1,559 +1,641 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
- */
2
+ * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
+ */
5
5
  /**
6
- * @module utils/observablemixin
7
- */
8
- import { type Emitter } from './emittermixin.js';
9
- import type { Constructor, Mixed } from './mix.js';
6
+ * @module utils/observablemixin
7
+ */
8
+ import { type Emitter } from "./emittermixin.js";
9
+ import type { Constructor, Mixed } from "./mix.js";
10
10
  /**
11
- * A mixin that injects the "observable properties" and data binding functionality described in the
12
- * {@link ~Observable} interface.
13
- *
14
- * This function creates a class that inherits from the provided `base` and implements `Observable` interface.
15
- *
16
- * ```ts
17
- * class BaseClass { ... }
18
- *
19
- * class MyClass extends ObservableMixin( BaseClass ) {
20
- * // This class derives from `BaseClass` and implements the `Observable` interface.
21
- * }
22
- * ```
23
- *
24
- * Read more about the concept of observables in the:
25
- * * {@glink framework/architecture/core-editor-architecture#event-system-and-observables Event system and observables}
26
- * section of the {@glink framework/architecture/core-editor-architecture Core editor architecture} guide,
27
- * * {@glink framework/deep-dive/observables Observables deep-dive} guide.
28
- *
29
- * @label EXTENDS
30
- */
31
- export declare function ObservableMixin<Base extends Constructor<Emitter>>(base: Base): Mixed<Base, Observable>;
32
- /**
33
- * A mixin that injects the "observable properties" and data binding functionality described in the
34
- * {@link ~Observable} interface.
35
- *
36
- * This function creates a class that implements `Observable` interface.
37
- *
38
- * ```ts
39
- * class MyClass extends ObservableMixin() {
40
- * // This class implements the `Observable` interface.
41
- * }
42
- * ```
43
- *
44
- * Read more about the concept of observables in the:
45
- * * {@glink framework/architecture/core-editor-architecture#event-system-and-observables Event system and observables}
46
- * section of the {@glink framework/architecture/core-editor-architecture Core editor architecture} guide,
47
- * * {@glink framework/deep-dive/observables Observables deep dive} guide.
48
- *
49
- * @label NO_ARGUMENTS
50
- */
51
- export declare function ObservableMixin(): {
52
- new (): Observable;
53
- prototype: Observable;
11
+ * Constructor returned by {@link ~ObservableMixin}. Use it to name a mixin base class before extending it.
12
+ *
13
+ * ```ts
14
+ * const MyObservableBase: ObservableMixinConstructor<typeof BaseClass> = ObservableMixin( BaseClass );
15
+ *
16
+ * class MyObservable extends MyObservableBase {}
17
+ * ```
18
+ */
19
+ export type ObservableMixinConstructor<Base extends Constructor<Emitter> | undefined = undefined> = Base extends Constructor<Emitter> ? Mixed<Base, Observable> : {
20
+ new (): Observable;
21
+ prototype: Observable;
54
22
  };
55
23
  /**
56
- * An interface which adds "observable properties" and data binding functionality.
57
- *
58
- * Can be easily implemented by a class by mixing the {@link module:utils/observablemixin~Observable} mixin.
59
- *
60
- * ```ts
61
- * class MyClass extends ObservableMixin( OtherBaseClass ) {
62
- * // This class now implements the `Observable` interface.
63
- * }
64
- * ```
65
- *
66
- * Read more about the usage of this interface in the:
67
- * * {@glink framework/architecture/core-editor-architecture#event-system-and-observables Event system and observables}
68
- * section of the {@glink framework/architecture/core-editor-architecture Core editor architecture} guide,
69
- * * {@glink framework/deep-dive/observables Observables deep-dive} guide.
70
- */
24
+ * A mixin that injects the "observable properties" and data binding functionality described in the
25
+ * {@link ~Observable} interface.
26
+ *
27
+ * This function creates a class that inherits from the provided `base` and implements `Observable` interface.
28
+ *
29
+ * ```ts
30
+ * class BaseClass { ... }
31
+ *
32
+ * class MyClass extends ObservableMixin( BaseClass ) {
33
+ * // This class derives from `BaseClass` and implements the `Observable` interface.
34
+ * }
35
+ * ```
36
+ *
37
+ * Read more about the concept of observables in the:
38
+ * * {@glink framework/architecture/core-editor-architecture#event-system-and-observables Event system and observables}
39
+ * section of the {@glink framework/architecture/core-editor-architecture Core editor architecture} guide,
40
+ * * {@glink framework/deep-dive/observables Observables deep-dive} guide.
41
+ *
42
+ * @label EXTENDS
43
+ */
44
+ export declare function ObservableMixin<Base extends Constructor<Emitter>>(base: Base): ObservableMixinConstructor<Base>;
45
+ /**
46
+ * A mixin that injects the "observable properties" and data binding functionality described in the
47
+ * {@link ~Observable} interface.
48
+ *
49
+ * This function creates a class that implements `Observable` interface.
50
+ *
51
+ * ```ts
52
+ * class MyClass extends ObservableMixin() {
53
+ * // This class implements the `Observable` interface.
54
+ * }
55
+ * ```
56
+ *
57
+ * Read more about the concept of observables in the:
58
+ * * {@glink framework/architecture/core-editor-architecture#event-system-and-observables Event system and observables}
59
+ * section of the {@glink framework/architecture/core-editor-architecture Core editor architecture} guide,
60
+ * * {@glink framework/deep-dive/observables Observables deep dive} guide.
61
+ *
62
+ * @label NO_ARGUMENTS
63
+ */
64
+ export declare function ObservableMixin(): ObservableMixinConstructor;
65
+ /**
66
+ * An interface which adds "observable properties" and data binding functionality.
67
+ *
68
+ * Can be easily implemented by a class by mixing the {@link module:utils/observablemixin~Observable} mixin.
69
+ *
70
+ * ```ts
71
+ * class MyClass extends ObservableMixin( OtherBaseClass ) {
72
+ * // This class now implements the `Observable` interface.
73
+ * }
74
+ * ```
75
+ *
76
+ * Read more about the usage of this interface in the:
77
+ * * {@glink framework/architecture/core-editor-architecture#event-system-and-observables Event system and observables}
78
+ * section of the {@glink framework/architecture/core-editor-architecture Core editor architecture} guide,
79
+ * * {@glink framework/deep-dive/observables Observables deep-dive} guide.
80
+ */
71
81
  export interface Observable extends Emitter {
72
- /**
73
- * Creates and sets the value of an observable property of this object. Such a property becomes a part
74
- * of the state and is observable.
75
- *
76
- * This method throws the `observable-set-cannot-override` error if the observable instance already
77
- * has a property with the given property name. This prevents from mistakenly overriding existing
78
- * properties and methods, but means that `foo.set( 'bar', 1 )` may be slightly slower than `foo.bar = 1`.
79
- *
80
- * In TypeScript, those properties should be declared in class using `declare` keyword. In example:
81
- *
82
- * ```ts
83
- * public declare myProp: number;
84
- *
85
- * constructor() {
86
- * this.set( 'myProp', 2 );
87
- * }
88
- * ```
89
- *
90
- * @label KEY_VALUE
91
- * @param name The property's name.
92
- * @param value The property's value.
93
- */
94
- set<K extends keyof this & string>(name: K, value: this[K]): void;
95
- /**
96
- * Creates and sets the value of an observable properties of this object. Such a property becomes a part
97
- * of the state and is observable.
98
- *
99
- * It accepts a single object literal containing key/value pairs with properties to be set.
100
- *
101
- * This method throws the `observable-set-cannot-override` error if the observable instance already
102
- * has a property with the given property name. This prevents from mistakenly overriding existing
103
- * properties and methods, but means that `foo.set( 'bar', 1 )` may be slightly slower than `foo.bar = 1`.
104
- *
105
- * In TypeScript, those properties should be declared in class using `declare` keyword. In example:
106
- *
107
- * ```ts
108
- * public declare myProp1: number;
109
- * public declare myProp2: string;
110
- *
111
- * constructor() {
112
- * this.set( {
113
- * 'myProp1: 2,
114
- * 'myProp2: 'foo'
115
- * } );
116
- * }
117
- * ```
118
- * @label OBJECT
119
- * @param values An object with `name=>value` pairs.
120
- */
121
- set(values: object & {
122
- readonly [K in keyof this]?: unknown;
123
- }): void;
124
- /**
125
- * Binds {@link #set observable properties} to other objects implementing the
126
- * {@link module:utils/observablemixin~Observable} interface.
127
- *
128
- * Read more in the {@glink framework/deep-dive/observables#property-bindings dedicated} guide
129
- * covering the topic of property bindings with some additional examples.
130
- *
131
- * Consider two objects: a `button` and an associated `command` (both `Observable`).
132
- *
133
- * A simple property binding could be as follows:
134
- *
135
- * ```ts
136
- * button.bind( 'isEnabled' ).to( command, 'isEnabled' );
137
- * ```
138
- *
139
- * or even shorter:
140
- *
141
- * ```ts
142
- * button.bind( 'isEnabled' ).to( command );
143
- * ```
144
- *
145
- * which works in the following way:
146
- *
147
- * * `button.isEnabled` **instantly equals** `command.isEnabled`,
148
- * * whenever `command.isEnabled` changes, `button.isEnabled` will immediately reflect its value.
149
- *
150
- * **Note**: To release the binding, use {@link module:utils/observablemixin~Observable#unbind}.
151
- *
152
- * You can also "rename" the property in the binding by specifying the new name in the `to()` chain:
153
- *
154
- * ```ts
155
- * button.bind( 'isEnabled' ).to( command, 'isWorking' );
156
- * ```
157
- *
158
- * It is possible to bind more than one property at a time to shorten the code:
159
- *
160
- * ```ts
161
- * button.bind( 'isEnabled', 'value' ).to( command );
162
- * ```
163
- *
164
- * which corresponds to:
165
- *
166
- * ```ts
167
- * button.bind( 'isEnabled' ).to( command );
168
- * button.bind( 'value' ).to( command );
169
- * ```
170
- *
171
- * The binding can include more than one observable, combining multiple data sources in a custom callback:
172
- *
173
- * ```ts
174
- * button.bind( 'isEnabled' ).to( command, 'isEnabled', ui, 'isVisible',
175
- * ( isCommandEnabled, isUIVisible ) => isCommandEnabled && isUIVisible );
176
- * ```
177
- *
178
- * Using a custom callback allows processing the value before passing it to the target property:
179
- *
180
- * ```ts
181
- * button.bind( 'isEnabled' ).to( command, 'value', value => value === 'heading1' );
182
- * ```
183
- *
184
- * It is also possible to bind to the same property in an array of observables.
185
- * To bind a `button` to multiple commands (also `Observables`) so that each and every one of them
186
- * must be enabled for the button to become enabled, use the following code:
187
- *
188
- * ```ts
189
- * button.bind( 'isEnabled' ).toMany( [ commandA, commandB, commandC ], 'isEnabled',
190
- * ( isAEnabled, isBEnabled, isCEnabled ) => isAEnabled && isBEnabled && isCEnabled );
191
- * ```
192
- *
193
- * @label SINGLE_BIND
194
- * @param bindProperty Observable property that will be bound to other observable(s).
195
- * @returns The bind chain with the `to()` and `toMany()` methods.
196
- */
197
- bind<K extends keyof this & string>(bindProperty: K): ObservableSingleBindChain<K, this[K]>;
198
- /**
199
- * Binds {@link #set observable properties} to other objects implementing the
200
- * {@link module:utils/observablemixin~Observable} interface.
201
- *
202
- * Read more in the {@glink framework/deep-dive/observables#property-bindings dedicated} guide
203
- * covering the topic of property bindings with some additional examples.
204
- *
205
- * Consider two objects: a `button` and an associated `command` (both `Observable`).
206
- *
207
- * A simple property binding could be as follows:
208
- *
209
- * ```ts
210
- * button.bind( 'isEnabled' ).to( command, 'isEnabled' );
211
- * ```
212
- *
213
- * or even shorter:
214
- *
215
- * ```ts
216
- * button.bind( 'isEnabled' ).to( command );
217
- * ```
218
- *
219
- * which works in the following way:
220
- *
221
- * * `button.isEnabled` **instantly equals** `command.isEnabled`,
222
- * * whenever `command.isEnabled` changes, `button.isEnabled` will immediately reflect its value.
223
- *
224
- * **Note**: To release the binding, use {@link module:utils/observablemixin~Observable#unbind}.
225
- *
226
- * You can also "rename" the property in the binding by specifying the new name in the `to()` chain:
227
- *
228
- * ```ts
229
- * button.bind( 'isEnabled' ).to( command, 'isWorking' );
230
- * ```
231
- *
232
- * It is possible to bind more than one property at a time to shorten the code:
233
- *
234
- * ```ts
235
- * button.bind( 'isEnabled', 'value' ).to( command );
236
- * ```
237
- *
238
- * which corresponds to:
239
- *
240
- * ```ts
241
- * button.bind( 'isEnabled' ).to( command );
242
- * button.bind( 'value' ).to( command );
243
- * ```
244
- *
245
- * The binding can include more than one observable, combining multiple data sources in a custom callback:
246
- *
247
- * ```ts
248
- * button.bind( 'isEnabled' ).to( command, 'isEnabled', ui, 'isVisible',
249
- * ( isCommandEnabled, isUIVisible ) => isCommandEnabled && isUIVisible );
250
- * ```
251
- *
252
- * Using a custom callback allows processing the value before passing it to the target property:
253
- *
254
- * ```ts
255
- * button.bind( 'isEnabled' ).to( command, 'value', value => value === 'heading1' );
256
- * ```
257
- *
258
- * It is also possible to bind to the same property in an array of observables.
259
- * To bind a `button` to multiple commands (also `Observables`) so that each and every one of them
260
- * must be enabled for the button to become enabled, use the following code:
261
- *
262
- * ```ts
263
- * button.bind( 'isEnabled' ).toMany( [ commandA, commandB, commandC ], 'isEnabled',
264
- * ( isAEnabled, isBEnabled, isCEnabled ) => isAEnabled && isBEnabled && isCEnabled );
265
- * ```
266
- *
267
- * @label DUAL_BIND
268
- * @param bindProperty1 Observable property that will be bound to other observable(s).
269
- * @param bindProperty2 Observable property that will be bound to other observable(s).
270
- * @returns The bind chain with the `to()` and `toMany()` methods.
271
- */
272
- bind<K1 extends keyof this & string, K2 extends keyof this & string>(bindProperty1: K1, bindProperty2: K2): ObservableDualBindChain<K1, this[K1], K2, this[K2]>;
273
- /**
274
- * Binds {@link #set observable properties} to other objects implementing the
275
- * {@link module:utils/observablemixin~Observable} interface.
276
- *
277
- * Read more in the {@glink framework/deep-dive/observables#property-bindings dedicated} guide
278
- * covering the topic of property bindings with some additional examples.
279
- *
280
- * Consider two objects: a `button` and an associated `command` (both `Observable`).
281
- *
282
- * A simple property binding could be as follows:
283
- *
284
- * ```ts
285
- * button.bind( 'isEnabled' ).to( command, 'isEnabled' );
286
- * ```
287
- *
288
- * or even shorter:
289
- *
290
- * ```ts
291
- * button.bind( 'isEnabled' ).to( command );
292
- * ```
293
- *
294
- * which works in the following way:
295
- *
296
- * * `button.isEnabled` **instantly equals** `command.isEnabled`,
297
- * * whenever `command.isEnabled` changes, `button.isEnabled` will immediately reflect its value.
298
- *
299
- * **Note**: To release the binding, use {@link module:utils/observablemixin~Observable#unbind}.
300
- *
301
- * You can also "rename" the property in the binding by specifying the new name in the `to()` chain:
302
- *
303
- * ```ts
304
- * button.bind( 'isEnabled' ).to( command, 'isWorking' );
305
- * ```
306
- *
307
- * It is possible to bind more than one property at a time to shorten the code:
308
- *
309
- * ```ts
310
- * button.bind( 'isEnabled', 'value' ).to( command );
311
- * ```
312
- *
313
- * which corresponds to:
314
- *
315
- * ```ts
316
- * button.bind( 'isEnabled' ).to( command );
317
- * button.bind( 'value' ).to( command );
318
- * ```
319
- *
320
- * The binding can include more than one observable, combining multiple data sources in a custom callback:
321
- *
322
- * ```ts
323
- * button.bind( 'isEnabled' ).to( command, 'isEnabled', ui, 'isVisible',
324
- * ( isCommandEnabled, isUIVisible ) => isCommandEnabled && isUIVisible );
325
- * ```
326
- *
327
- * Using a custom callback allows processing the value before passing it to the target property:
328
- *
329
- * ```ts
330
- * button.bind( 'isEnabled' ).to( command, 'value', value => value === 'heading1' );
331
- * ```
332
- *
333
- * It is also possible to bind to the same property in an array of observables.
334
- * To bind a `button` to multiple commands (also `Observables`) so that each and every one of them
335
- * must be enabled for the button to become enabled, use the following code:
336
- *
337
- * ```ts
338
- * button.bind( 'isEnabled' ).toMany( [ commandA, commandB, commandC ], 'isEnabled',
339
- * ( isAEnabled, isBEnabled, isCEnabled ) => isAEnabled && isBEnabled && isCEnabled );
340
- * ```
341
- *
342
- * @label MANY_BIND
343
- * @param bindProperties Observable properties that will be bound to other observable(s).
344
- * @returns The bind chain with the `to()` and `toMany()` methods.
345
- */
346
- bind(...bindProperties: Array<keyof this & string>): ObservableMultiBindChain;
347
- /**
348
- * Removes the binding created with {@link #bind}.
349
- *
350
- * ```ts
351
- * // Removes the binding for the 'a' property.
352
- * A.unbind( 'a' );
353
- *
354
- * // Removes bindings for all properties.
355
- * A.unbind();
356
- * ```
357
- *
358
- * @param unbindProperties Observable properties to be unbound. All the bindings will
359
- * be released if no properties are provided.
360
- */
361
- unbind(...unbindProperties: Array<keyof this & string>): void;
362
- /**
363
- * Turns the given methods of this object into event-based ones. This means that the new method will fire an event
364
- * (named after the method) and the original action will be plugged as a listener to that event.
365
- *
366
- * Read more in the {@glink framework/deep-dive/observables#decorating-object-methods dedicated} guide
367
- * covering the topic of decorating methods with some additional examples.
368
- *
369
- * Decorating the method does not change its behavior (it only adds an event),
370
- * but it allows to modify it later on by listening to the method's event.
371
- *
372
- * For example, to cancel the method execution the event can be {@link module:utils/eventinfo~EventInfo#stop stopped}:
373
- *
374
- * ```ts
375
- * class Foo extends ObservableMixin() {
376
- * constructor() {
377
- * super();
378
- * this.decorate( 'method' );
379
- * }
380
- *
381
- * method() {
382
- * console.log( 'called!' );
383
- * }
384
- * }
385
- *
386
- * const foo = new Foo();
387
- * foo.on( 'method', ( evt ) => {
388
- * evt.stop();
389
- * }, { priority: 'high' } );
390
- *
391
- * foo.method(); // Nothing is logged.
392
- * ```
393
- *
394
- *
395
- * **Note**: The high {@link module:utils/priorities~PriorityString priority} listener
396
- * has been used to execute this particular callback before the one which calls the original method
397
- * (which uses the "normal" priority).
398
- *
399
- * It is also possible to change the returned value:
400
- *
401
- * ```ts
402
- * foo.on( 'method', ( evt ) => {
403
- * evt.return = 'Foo!';
404
- * } );
405
- *
406
- * foo.method(); // -> 'Foo'
407
- * ```
408
- *
409
- * Finally, it is possible to access and modify the arguments the method is called with:
410
- *
411
- * ```ts
412
- * method( a, b ) {
413
- * console.log( `${ a }, ${ b }` );
414
- * }
415
- *
416
- * // ...
417
- *
418
- * foo.on( 'method', ( evt, args ) => {
419
- * args[ 0 ] = 3;
420
- *
421
- * console.log( args[ 1 ] ); // -> 2
422
- * }, { priority: 'high' } );
423
- *
424
- * foo.method( 1, 2 ); // -> '3, 2'
425
- * ```
426
- *
427
- * @param methodName Name of the method to decorate.
428
- */
429
- decorate(methodName: keyof this & string): void;
82
+ /**
83
+ * Creates and sets the value of an observable property of this object. Such a property becomes a part
84
+ * of the state and is observable.
85
+ *
86
+ * This method throws the `observable-set-cannot-override` error if the observable instance already
87
+ * has a property with the given property name. This prevents from mistakenly overriding existing
88
+ * properties and methods, but means that `foo.set( 'bar', 1 )` may be slightly slower than `foo.bar = 1`.
89
+ *
90
+ * In TypeScript, those properties should be declared in class using `declare` keyword. In example:
91
+ *
92
+ * ```ts
93
+ * public declare myProp: number;
94
+ *
95
+ * constructor() {
96
+ * this.set( 'myProp', 2 );
97
+ * }
98
+ * ```
99
+ *
100
+ * @label KEY_VALUE
101
+ * @param name The property's name.
102
+ * @param value The property's value.
103
+ */
104
+ set<K extends keyof this & string>(name: K, value: this[K]): void;
105
+ /**
106
+ * Creates and sets the value of an observable properties of this object. Such a property becomes a part
107
+ * of the state and is observable.
108
+ *
109
+ * It accepts a single object literal containing key/value pairs with properties to be set.
110
+ *
111
+ * This method throws the `observable-set-cannot-override` error if the observable instance already
112
+ * has a property with the given property name. This prevents from mistakenly overriding existing
113
+ * properties and methods, but means that `foo.set( 'bar', 1 )` may be slightly slower than `foo.bar = 1`.
114
+ *
115
+ * In TypeScript, those properties should be declared in class using `declare` keyword. In example:
116
+ *
117
+ * ```ts
118
+ * public declare myProp1: number;
119
+ * public declare myProp2: string;
120
+ *
121
+ * constructor() {
122
+ * this.set( {
123
+ * 'myProp1: 2,
124
+ * 'myProp2: 'foo'
125
+ * } );
126
+ * }
127
+ * ```
128
+ * @label OBJECT
129
+ * @param values An object with `name=>value` pairs.
130
+ */
131
+ set(values: object & { readonly [K in keyof this]?: unknown }): void;
132
+ /**
133
+ * Binds {@link #set observable properties} to other objects implementing the
134
+ * {@link module:utils/observablemixin~Observable} interface.
135
+ *
136
+ * Read more in the {@glink framework/deep-dive/observables#property-bindings dedicated} guide
137
+ * covering the topic of property bindings with some additional examples.
138
+ *
139
+ * Consider two objects: a `button` and an associated `command` (both `Observable`).
140
+ *
141
+ * A simple property binding could be as follows:
142
+ *
143
+ * ```ts
144
+ * button.bind( 'isEnabled' ).to( command, 'isEnabled' );
145
+ * ```
146
+ *
147
+ * or even shorter:
148
+ *
149
+ * ```ts
150
+ * button.bind( 'isEnabled' ).to( command );
151
+ * ```
152
+ *
153
+ * which works in the following way:
154
+ *
155
+ * * `button.isEnabled` **instantly equals** `command.isEnabled`,
156
+ * * whenever `command.isEnabled` changes, `button.isEnabled` will immediately reflect its value.
157
+ *
158
+ * **Note**: To release the binding, use {@link module:utils/observablemixin~Observable#unbind}.
159
+ *
160
+ * You can also "rename" the property in the binding by specifying the new name in the `to()` chain:
161
+ *
162
+ * ```ts
163
+ * button.bind( 'isEnabled' ).to( command, 'isWorking' );
164
+ * ```
165
+ *
166
+ * It is possible to bind more than one property at a time to shorten the code:
167
+ *
168
+ * ```ts
169
+ * button.bind( 'isEnabled', 'value' ).to( command );
170
+ * ```
171
+ *
172
+ * which corresponds to:
173
+ *
174
+ * ```ts
175
+ * button.bind( 'isEnabled' ).to( command );
176
+ * button.bind( 'value' ).to( command );
177
+ * ```
178
+ *
179
+ * The binding can include more than one observable, combining multiple data sources in a custom callback:
180
+ *
181
+ * ```ts
182
+ * button.bind( 'isEnabled' ).to( command, 'isEnabled', ui, 'isVisible',
183
+ * ( isCommandEnabled, isUIVisible ) => isCommandEnabled && isUIVisible );
184
+ * ```
185
+ *
186
+ * Using a custom callback allows processing the value before passing it to the target property:
187
+ *
188
+ * ```ts
189
+ * button.bind( 'isEnabled' ).to( command, 'value', value => value === 'heading1' );
190
+ * ```
191
+ *
192
+ * It is also possible to bind to the same property in an array of observables.
193
+ * To bind a `button` to multiple commands (also `Observables`) so that each and every one of them
194
+ * must be enabled for the button to become enabled, use the following code:
195
+ *
196
+ * ```ts
197
+ * button.bind( 'isEnabled' ).toMany( [ commandA, commandB, commandC ], 'isEnabled',
198
+ * ( isAEnabled, isBEnabled, isCEnabled ) => isAEnabled && isBEnabled && isCEnabled );
199
+ * ```
200
+ *
201
+ * @label SINGLE_BIND
202
+ * @param bindProperty Observable property that will be bound to other observable(s).
203
+ * @returns The bind chain with the `to()` and `toMany()` methods.
204
+ */
205
+ bind<K extends keyof this & string>(bindProperty: K): ObservableSingleBindChain<K, this[K]>;
206
+ /**
207
+ * Binds {@link #set observable properties} to other objects implementing the
208
+ * {@link module:utils/observablemixin~Observable} interface.
209
+ *
210
+ * Read more in the {@glink framework/deep-dive/observables#property-bindings dedicated} guide
211
+ * covering the topic of property bindings with some additional examples.
212
+ *
213
+ * Consider two objects: a `button` and an associated `command` (both `Observable`).
214
+ *
215
+ * A simple property binding could be as follows:
216
+ *
217
+ * ```ts
218
+ * button.bind( 'isEnabled' ).to( command, 'isEnabled' );
219
+ * ```
220
+ *
221
+ * or even shorter:
222
+ *
223
+ * ```ts
224
+ * button.bind( 'isEnabled' ).to( command );
225
+ * ```
226
+ *
227
+ * which works in the following way:
228
+ *
229
+ * * `button.isEnabled` **instantly equals** `command.isEnabled`,
230
+ * * whenever `command.isEnabled` changes, `button.isEnabled` will immediately reflect its value.
231
+ *
232
+ * **Note**: To release the binding, use {@link module:utils/observablemixin~Observable#unbind}.
233
+ *
234
+ * You can also "rename" the property in the binding by specifying the new name in the `to()` chain:
235
+ *
236
+ * ```ts
237
+ * button.bind( 'isEnabled' ).to( command, 'isWorking' );
238
+ * ```
239
+ *
240
+ * It is possible to bind more than one property at a time to shorten the code:
241
+ *
242
+ * ```ts
243
+ * button.bind( 'isEnabled', 'value' ).to( command );
244
+ * ```
245
+ *
246
+ * which corresponds to:
247
+ *
248
+ * ```ts
249
+ * button.bind( 'isEnabled' ).to( command );
250
+ * button.bind( 'value' ).to( command );
251
+ * ```
252
+ *
253
+ * The binding can include more than one observable, combining multiple data sources in a custom callback:
254
+ *
255
+ * ```ts
256
+ * button.bind( 'isEnabled' ).to( command, 'isEnabled', ui, 'isVisible',
257
+ * ( isCommandEnabled, isUIVisible ) => isCommandEnabled && isUIVisible );
258
+ * ```
259
+ *
260
+ * Using a custom callback allows processing the value before passing it to the target property:
261
+ *
262
+ * ```ts
263
+ * button.bind( 'isEnabled' ).to( command, 'value', value => value === 'heading1' );
264
+ * ```
265
+ *
266
+ * It is also possible to bind to the same property in an array of observables.
267
+ * To bind a `button` to multiple commands (also `Observables`) so that each and every one of them
268
+ * must be enabled for the button to become enabled, use the following code:
269
+ *
270
+ * ```ts
271
+ * button.bind( 'isEnabled' ).toMany( [ commandA, commandB, commandC ], 'isEnabled',
272
+ * ( isAEnabled, isBEnabled, isCEnabled ) => isAEnabled && isBEnabled && isCEnabled );
273
+ * ```
274
+ *
275
+ * @label DUAL_BIND
276
+ * @param bindProperty1 Observable property that will be bound to other observable(s).
277
+ * @param bindProperty2 Observable property that will be bound to other observable(s).
278
+ * @returns The bind chain with the `to()` and `toMany()` methods.
279
+ */
280
+ bind<
281
+ K1 extends keyof this & string,
282
+ K2 extends keyof this & string
283
+ >(bindProperty1: K1, bindProperty2: K2): ObservableDualBindChain<K1, this[K1], K2, this[K2]>;
284
+ /**
285
+ * Binds {@link #set observable properties} to other objects implementing the
286
+ * {@link module:utils/observablemixin~Observable} interface.
287
+ *
288
+ * Read more in the {@glink framework/deep-dive/observables#property-bindings dedicated} guide
289
+ * covering the topic of property bindings with some additional examples.
290
+ *
291
+ * Consider two objects: a `button` and an associated `command` (both `Observable`).
292
+ *
293
+ * A simple property binding could be as follows:
294
+ *
295
+ * ```ts
296
+ * button.bind( 'isEnabled' ).to( command, 'isEnabled' );
297
+ * ```
298
+ *
299
+ * or even shorter:
300
+ *
301
+ * ```ts
302
+ * button.bind( 'isEnabled' ).to( command );
303
+ * ```
304
+ *
305
+ * which works in the following way:
306
+ *
307
+ * * `button.isEnabled` **instantly equals** `command.isEnabled`,
308
+ * * whenever `command.isEnabled` changes, `button.isEnabled` will immediately reflect its value.
309
+ *
310
+ * **Note**: To release the binding, use {@link module:utils/observablemixin~Observable#unbind}.
311
+ *
312
+ * You can also "rename" the property in the binding by specifying the new name in the `to()` chain:
313
+ *
314
+ * ```ts
315
+ * button.bind( 'isEnabled' ).to( command, 'isWorking' );
316
+ * ```
317
+ *
318
+ * It is possible to bind more than one property at a time to shorten the code:
319
+ *
320
+ * ```ts
321
+ * button.bind( 'isEnabled', 'value' ).to( command );
322
+ * ```
323
+ *
324
+ * which corresponds to:
325
+ *
326
+ * ```ts
327
+ * button.bind( 'isEnabled' ).to( command );
328
+ * button.bind( 'value' ).to( command );
329
+ * ```
330
+ *
331
+ * The binding can include more than one observable, combining multiple data sources in a custom callback:
332
+ *
333
+ * ```ts
334
+ * button.bind( 'isEnabled' ).to( command, 'isEnabled', ui, 'isVisible',
335
+ * ( isCommandEnabled, isUIVisible ) => isCommandEnabled && isUIVisible );
336
+ * ```
337
+ *
338
+ * Using a custom callback allows processing the value before passing it to the target property:
339
+ *
340
+ * ```ts
341
+ * button.bind( 'isEnabled' ).to( command, 'value', value => value === 'heading1' );
342
+ * ```
343
+ *
344
+ * It is also possible to bind to the same property in an array of observables.
345
+ * To bind a `button` to multiple commands (also `Observables`) so that each and every one of them
346
+ * must be enabled for the button to become enabled, use the following code:
347
+ *
348
+ * ```ts
349
+ * button.bind( 'isEnabled' ).toMany( [ commandA, commandB, commandC ], 'isEnabled',
350
+ * ( isAEnabled, isBEnabled, isCEnabled ) => isAEnabled && isBEnabled && isCEnabled );
351
+ * ```
352
+ *
353
+ * @label MANY_BIND
354
+ * @param bindProperties Observable properties that will be bound to other observable(s).
355
+ * @returns The bind chain with the `to()` and `toMany()` methods.
356
+ */
357
+ bind(...bindProperties: Array<keyof this & string>): ObservableMultiBindChain;
358
+ /**
359
+ * Removes the binding created with {@link #bind}.
360
+ *
361
+ * ```ts
362
+ * // Removes the binding for the 'a' property.
363
+ * A.unbind( 'a' );
364
+ *
365
+ * // Removes bindings for all properties.
366
+ * A.unbind();
367
+ * ```
368
+ *
369
+ * @param unbindProperties Observable properties to be unbound. All the bindings will
370
+ * be released if no properties are provided.
371
+ */
372
+ unbind(...unbindProperties: Array<keyof this & string>): void;
373
+ /**
374
+ * Turns the given methods of this object into event-based ones. This means that the new method will fire an event
375
+ * (named after the method) and the original action will be plugged as a listener to that event.
376
+ *
377
+ * Read more in the {@glink framework/deep-dive/observables#decorating-object-methods dedicated} guide
378
+ * covering the topic of decorating methods with some additional examples.
379
+ *
380
+ * Decorating the method does not change its behavior (it only adds an event),
381
+ * but it allows to modify it later on by listening to the method's event.
382
+ *
383
+ * For example, to cancel the method execution the event can be {@link module:utils/eventinfo~EventInfo#stop stopped}:
384
+ *
385
+ * ```ts
386
+ * class Foo extends ObservableMixin() {
387
+ * constructor() {
388
+ * super();
389
+ * this.decorate( 'method' );
390
+ * }
391
+ *
392
+ * method() {
393
+ * console.log( 'called!' );
394
+ * }
395
+ * }
396
+ *
397
+ * const foo = new Foo();
398
+ * foo.on( 'method', ( evt ) => {
399
+ * evt.stop();
400
+ * }, { priority: 'high' } );
401
+ *
402
+ * foo.method(); // Nothing is logged.
403
+ * ```
404
+ *
405
+ *
406
+ * **Note**: The high {@link module:utils/priorities~PriorityString priority} listener
407
+ * has been used to execute this particular callback before the one which calls the original method
408
+ * (which uses the "normal" priority).
409
+ *
410
+ * It is also possible to change the returned value:
411
+ *
412
+ * ```ts
413
+ * foo.on( 'method', ( evt ) => {
414
+ * evt.return = 'Foo!';
415
+ * } );
416
+ *
417
+ * foo.method(); // -> 'Foo'
418
+ * ```
419
+ *
420
+ * Finally, it is possible to access and modify the arguments the method is called with:
421
+ *
422
+ * ```ts
423
+ * method( a, b ) {
424
+ * console.log( `${ a }, ${ b }` );
425
+ * }
426
+ *
427
+ * // ...
428
+ *
429
+ * foo.on( 'method', ( evt, args ) => {
430
+ * args[ 0 ] = 3;
431
+ *
432
+ * console.log( args[ 1 ] ); // -> 2
433
+ * }, { priority: 'high' } );
434
+ *
435
+ * foo.method( 1, 2 ); // -> '3, 2'
436
+ * ```
437
+ *
438
+ * @param methodName Name of the method to decorate.
439
+ */
440
+ decorate(methodName: keyof this & string): void;
430
441
  }
431
442
  /**
432
- * Fired when a property changed value.
433
- *
434
- * ```ts
435
- * observable.set( 'prop', 1 );
436
- *
437
- * observable.on<ObservableChangeEvent<number>>( 'change:prop', ( evt, propertyName, newValue, oldValue ) => {
438
- * console.log( `${ propertyName } has changed from ${ oldValue } to ${ newValue }` );
439
- * } );
440
- *
441
- * observable.prop = 2; // -> 'prop has changed from 1 to 2'
442
- * ```
443
- *
444
- * @eventName ~Observable#change:\{property\}
445
- * @param {String} name The property name.
446
- * @param {*} value The new property value.
447
- * @param {*} oldValue The previous property value.
448
- */
443
+ * Fired when a property changed value.
444
+ *
445
+ * ```ts
446
+ * observable.set( 'prop', 1 );
447
+ *
448
+ * observable.on<ObservableChangeEvent<number>>( 'change:prop', ( evt, propertyName, newValue, oldValue ) => {
449
+ * console.log( `${ propertyName } has changed from ${ oldValue } to ${ newValue }` );
450
+ * } );
451
+ *
452
+ * observable.prop = 2; // -> 'prop has changed from 1 to 2'
453
+ * ```
454
+ *
455
+ * @eventName ~Observable#change:\{property\}
456
+ * @param {String} name The property name.
457
+ * @param {*} value The new property value.
458
+ * @param {*} oldValue The previous property value.
459
+ */
449
460
  export type ObservableChangeEvent<TValue = any> = {
450
- name: 'change' | `change:${string}`;
451
- args: [name: string, value: TValue, oldValue: TValue];
461
+ name: "change" | `change:${string}`;
462
+ args: [name: string, value: TValue, oldValue: TValue];
452
463
  };
453
464
  /**
454
- * Fired when a property value is going to be set but is not set yet (before the `change` event is fired).
455
- *
456
- * You can control the final value of the property by using
457
- * the {@link module:utils/eventinfo~EventInfo#return event's `return` property}.
458
- *
459
- * ```ts
460
- * observable.set( 'prop', 1 );
461
- *
462
- * observable.on<ObservableSetEvent<number>>( 'set:prop', ( evt, propertyName, newValue, oldValue ) => {
463
- * console.log( `Value is going to be changed from ${ oldValue } to ${ newValue }` );
464
- * console.log( `Current property value is ${ observable[ propertyName ] }` );
465
- *
466
- * // Let's override the value.
467
- * evt.return = 3;
468
- * } );
469
- *
470
- * observable.on<ObservableChangeEvent<number>>( 'change:prop', ( evt, propertyName, newValue, oldValue ) => {
471
- * console.log( `Value has changed from ${ oldValue } to ${ newValue }` );
472
- * } );
473
- *
474
- * observable.prop = 2; // -> 'Value is going to be changed from 1 to 2'
475
- * // -> 'Current property value is 1'
476
- * // -> 'Value has changed from 1 to 3'
477
- * ```
478
- *
479
- * **Note:** The event is fired even when the new value is the same as the old value.
480
- *
481
- * @eventName ~Observable#set:\{property\}
482
- * @param {String} name The property name.
483
- * @param {*} value The new property value.
484
- * @param {*} oldValue The previous property value.
485
- */
465
+ * Fired when a property value is going to be set but is not set yet (before the `change` event is fired).
466
+ *
467
+ * You can control the final value of the property by using
468
+ * the {@link module:utils/eventinfo~EventInfo#return event's `return` property}.
469
+ *
470
+ * ```ts
471
+ * observable.set( 'prop', 1 );
472
+ *
473
+ * observable.on<ObservableSetEvent<number>>( 'set:prop', ( evt, propertyName, newValue, oldValue ) => {
474
+ * console.log( `Value is going to be changed from ${ oldValue } to ${ newValue }` );
475
+ * console.log( `Current property value is ${ observable[ propertyName ] }` );
476
+ *
477
+ * // Let's override the value.
478
+ * evt.return = 3;
479
+ * } );
480
+ *
481
+ * observable.on<ObservableChangeEvent<number>>( 'change:prop', ( evt, propertyName, newValue, oldValue ) => {
482
+ * console.log( `Value has changed from ${ oldValue } to ${ newValue }` );
483
+ * } );
484
+ *
485
+ * observable.prop = 2; // -> 'Value is going to be changed from 1 to 2'
486
+ * // -> 'Current property value is 1'
487
+ * // -> 'Value has changed from 1 to 3'
488
+ * ```
489
+ *
490
+ * **Note:** The event is fired even when the new value is the same as the old value.
491
+ *
492
+ * @eventName ~Observable#set:\{property\}
493
+ * @param {String} name The property name.
494
+ * @param {*} value The new property value.
495
+ * @param {*} oldValue The previous property value.
496
+ */
486
497
  export type ObservableSetEvent<TValue = any> = {
487
- name: 'set' | `set:${string}`;
488
- args: [name: string, value: TValue, oldValue: TValue];
489
- return: TValue;
498
+ name: "set" | `set:${string}`;
499
+ args: [name: string, value: TValue, oldValue: TValue];
500
+ return: TValue;
490
501
  };
491
502
  /**
492
- * Utility type that creates an event describing type from decorated method.
493
- *
494
- * ```ts
495
- * class Foo extends ObservableMixin() {
496
- * constructor() {
497
- * super();
498
- * this.decorate( 'method' );
499
- * }
500
- *
501
- * method( a: number, b: number ): number {
502
- * return a + b;
503
- * }
504
- * }
505
- *
506
- * type FooMethodEvent = DecoratedMethodEvent<Foo, 'method'>;
507
- *
508
- * const foo = new Foo();
509
- *
510
- * foo.on<FooMethodEvent>( 'method', ( evt, [ a, b ] ) => {
511
- * // `a` and `b` are inferred as numbers.
512
- * } )
513
- * ```
514
- */
515
- export type DecoratedMethodEvent<TObservable extends Observable & {
516
- [N in TName]: (...args: Array<any>) => any;
517
- }, TName extends keyof TObservable & string> = {
518
- name: TName;
519
- args: [Parameters<TObservable[TName]>];
520
- return: ReturnType<TObservable[TName]>;
503
+ * Utility type that creates an event describing type from decorated method.
504
+ *
505
+ * ```ts
506
+ * class Foo extends ObservableMixin() {
507
+ * constructor() {
508
+ * super();
509
+ * this.decorate( 'method' );
510
+ * }
511
+ *
512
+ * method( a: number, b: number ): number {
513
+ * return a + b;
514
+ * }
515
+ * }
516
+ *
517
+ * type FooMethodEvent = DecoratedMethodEvent<Foo, 'method'>;
518
+ *
519
+ * const foo = new Foo();
520
+ *
521
+ * foo.on<FooMethodEvent>( 'method', ( evt, [ a, b ] ) => {
522
+ * // `a` and `b` are inferred as numbers.
523
+ * } )
524
+ * ```
525
+ */
526
+ export type DecoratedMethodEvent<
527
+ TObservable extends Observable & { [N in TName]: (...args: Array<any>) => any },
528
+ TName extends keyof TObservable & string
529
+ > = {
530
+ name: TName;
531
+ args: [Parameters<TObservable[TName]>];
532
+ return: ReturnType<TObservable[TName]>;
521
533
  };
522
- export interface ObservableSingleBindChain<TKey extends string, TVal> {
523
- toMany<O extends Observable, K extends keyof O>(observables: ReadonlyArray<O>, key: K, callback: (...values: Array<O[K]>) => TVal): void;
524
- to<O extends ObservableWithProperty<TKey, TVal>>(observable: O): void;
525
- to<O extends ObservableWithProperty<TKey>>(observable: O, callback: (value: O[TKey]) => TVal): void;
526
- to<O extends ObservableWithProperty<K, TVal>, K extends keyof O>(observable: O, key: K): void;
527
- to<O extends Observable, K extends keyof O>(observable: O, key: K, callback: (value: O[K]) => TVal): void;
528
- to<O1 extends ObservableWithProperty<TKey>, O2 extends ObservableWithProperty<TKey>>(observable1: O1, observable2: O2, callback: (value1: O1[TKey], value2: O2[TKey]) => TVal): void;
529
- to<O1 extends Observable, K1 extends keyof O1, O2 extends Observable, K2 extends keyof O2>(observable1: O1, key1: K1, observable2: O2, key2: K2, callback: (value1: O1[K1], value2: O2[K2]) => TVal): void;
530
- to<O1 extends ObservableWithProperty<TKey>, O2 extends ObservableWithProperty<TKey>, O3 extends ObservableWithProperty<TKey>>(observable1: O1, observable2: O2, observable3: O3, callback: (value1: O1[TKey], value2: O2[TKey], value3: O3[TKey]) => TVal): void;
531
- to<O1 extends Observable, K1 extends keyof O1, O2 extends Observable, K2 extends keyof O2, O3 extends Observable, K3 extends keyof O3>(observable1: O1, key1: K1, observable2: O2, key2: K2, observable3: O3, key3: K3, callback: (value1: O1[K1], value2: O2[K2], value3: O3[K3]) => TVal): void;
532
- to<O1 extends ObservableWithProperty<TKey>, O2 extends ObservableWithProperty<TKey>, O3 extends ObservableWithProperty<TKey>, O4 extends ObservableWithProperty<TKey>>(observable1: O1, observable2: O2, observable3: O3, observable4: O4, callback: (value1: O1[TKey], value2: O2[TKey], value3: O3[TKey], value4: O4[TKey]) => TVal): void;
533
- to<O1 extends Observable, K1 extends keyof O1, O2 extends Observable, K2 extends keyof O2, O3 extends Observable, K3 extends keyof O3, O4 extends Observable, K4 extends keyof O4>(observable1: O1, key1: K1, observable2: O2, key2: K2, observable3: O3, key3: K3, observable4: O4, key4: K4, callback: (value1: O1[K1], value2: O2[K2], value3: O3[K3], value4: O4[K4]) => TVal): void;
534
- to<O1 extends ObservableWithProperty<TKey>, O2 extends ObservableWithProperty<TKey>, O3 extends ObservableWithProperty<TKey>, O4 extends ObservableWithProperty<TKey>, O5 extends ObservableWithProperty<TKey>>(observable1: O1, observable2: O2, observable3: O3, observable4: O4, observable5: O5, callback: (value1: O1[TKey], value2: O2[TKey], value3: O3[TKey], value4: O4[TKey], value5: O5[TKey]) => TVal): void;
535
- to<O1 extends Observable, K1 extends keyof O1, O2 extends Observable, K2 extends keyof O2, O3 extends Observable, K3 extends keyof O3, O4 extends Observable, K4 extends keyof O4, O5 extends Observable, K5 extends keyof O5>(observable1: O1, key1: K1, observable2: O2, key2: K2, observable3: O3, key3: K3, observable4: O4, key4: K4, observable5: O5, key5: K5, callback: (value1: O1[K1], value2: O2[K2], value3: O3[K3], value4: O4[K4], value5: O5[K5]) => TVal): void;
534
+ export interface ObservableSingleBindChain<
535
+ TKey extends string,
536
+ TVal
537
+ > {
538
+ toMany<
539
+ O extends Observable,
540
+ K extends keyof O
541
+ >(observables: ReadonlyArray<O>, key: K, callback: (...values: Array<O[K]>) => TVal): void;
542
+ to<O extends ObservableWithProperty<TKey, TVal>>(observable: O): void;
543
+ to<O extends ObservableWithProperty<TKey>>(observable: O, callback: (value: O[TKey]) => TVal): void;
544
+ to<
545
+ O extends ObservableWithProperty<K, TVal>,
546
+ K extends keyof O
547
+ >(observable: O, key: K): void;
548
+ to<
549
+ O extends Observable,
550
+ K extends keyof O
551
+ >(observable: O, key: K, callback: (value: O[K]) => TVal): void;
552
+ to<
553
+ O1 extends ObservableWithProperty<TKey>,
554
+ O2 extends ObservableWithProperty<TKey>
555
+ >(observable1: O1, observable2: O2, callback: (value1: O1[TKey], value2: O2[TKey]) => TVal): void;
556
+ to<
557
+ O1 extends Observable,
558
+ K1 extends keyof O1,
559
+ O2 extends Observable,
560
+ K2 extends keyof O2
561
+ >(observable1: O1, key1: K1, observable2: O2, key2: K2, callback: (value1: O1[K1], value2: O2[K2]) => TVal): void;
562
+ to<
563
+ O1 extends ObservableWithProperty<TKey>,
564
+ O2 extends ObservableWithProperty<TKey>,
565
+ O3 extends ObservableWithProperty<TKey>
566
+ >(observable1: O1, observable2: O2, observable3: O3, callback: (value1: O1[TKey], value2: O2[TKey], value3: O3[TKey]) => TVal): void;
567
+ to<
568
+ O1 extends Observable,
569
+ K1 extends keyof O1,
570
+ O2 extends Observable,
571
+ K2 extends keyof O2,
572
+ O3 extends Observable,
573
+ K3 extends keyof O3
574
+ >(observable1: O1, key1: K1, observable2: O2, key2: K2, observable3: O3, key3: K3, callback: (value1: O1[K1], value2: O2[K2], value3: O3[K3]) => TVal): void;
575
+ to<
576
+ O1 extends ObservableWithProperty<TKey>,
577
+ O2 extends ObservableWithProperty<TKey>,
578
+ O3 extends ObservableWithProperty<TKey>,
579
+ O4 extends ObservableWithProperty<TKey>
580
+ >(observable1: O1, observable2: O2, observable3: O3, observable4: O4, callback: (value1: O1[TKey], value2: O2[TKey], value3: O3[TKey], value4: O4[TKey]) => TVal): void;
581
+ to<
582
+ O1 extends Observable,
583
+ K1 extends keyof O1,
584
+ O2 extends Observable,
585
+ K2 extends keyof O2,
586
+ O3 extends Observable,
587
+ K3 extends keyof O3,
588
+ O4 extends Observable,
589
+ K4 extends keyof O4
590
+ >(observable1: O1, key1: K1, observable2: O2, key2: K2, observable3: O3, key3: K3, observable4: O4, key4: K4, callback: (value1: O1[K1], value2: O2[K2], value3: O3[K3], value4: O4[K4]) => TVal): void;
591
+ to<
592
+ O1 extends ObservableWithProperty<TKey>,
593
+ O2 extends ObservableWithProperty<TKey>,
594
+ O3 extends ObservableWithProperty<TKey>,
595
+ O4 extends ObservableWithProperty<TKey>,
596
+ O5 extends ObservableWithProperty<TKey>
597
+ >(observable1: O1, observable2: O2, observable3: O3, observable4: O4, observable5: O5, callback: (value1: O1[TKey], value2: O2[TKey], value3: O3[TKey], value4: O4[TKey], value5: O5[TKey]) => TVal): void;
598
+ to<
599
+ O1 extends Observable,
600
+ K1 extends keyof O1,
601
+ O2 extends Observable,
602
+ K2 extends keyof O2,
603
+ O3 extends Observable,
604
+ K3 extends keyof O3,
605
+ O4 extends Observable,
606
+ K4 extends keyof O4,
607
+ O5 extends Observable,
608
+ K5 extends keyof O5
609
+ >(observable1: O1, key1: K1, observable2: O2, key2: K2, observable3: O3, key3: K3, observable4: O4, key4: K4, observable5: O5, key5: K5, callback: (value1: O1[K1], value2: O2[K2], value3: O3[K3], value4: O4[K4], value5: O5[K5]) => TVal): void;
536
610
  }
537
611
  /**
538
- * A helper type that can be used as a constraint, ensuring the type is both observable and have the given property.
539
- *
540
- * ```ts
541
- * // Ensures that `obj` is `Observable` and have property named 'abc'.
542
- * function f<O extends ObservableWithProperty<'abc'>>( obj: O ) {}
543
- *
544
- * // Ensures that `obj` is `Observable` and have property named 'abc' with value `number`.
545
- * function f<O extends ObservableWithProperty<'abc', number>>( obj: O ) {}
546
- * ```
547
- */
548
- export type ObservableWithProperty<TKey extends PropertyKey, TVal = any> = undefined extends TVal ? Observable & {
549
- [P in TKey]?: TVal;
550
- } : Observable & {
551
- [P in TKey]: TVal;
552
- };
553
- export interface ObservableDualBindChain<TKey1 extends string, TVal1, TKey2 extends string, TVal2> {
554
- to<O extends ObservableWithProperty<K1, TVal1> & ObservableWithProperty<K2, TVal2>, K1 extends keyof O, K2 extends keyof O>(observable: O, key1: K1, key2: K2): void;
555
- to<O extends ObservableWithProperty<TKey1, TVal1> & ObservableWithProperty<TKey2, TVal2>>(observable: O): void;
612
+ * A helper type that can be used as a constraint, ensuring the type is both observable and have the given property.
613
+ *
614
+ * ```ts
615
+ * // Ensures that `obj` is `Observable` and have property named 'abc'.
616
+ * function f<O extends ObservableWithProperty<'abc'>>( obj: O ) {}
617
+ *
618
+ * // Ensures that `obj` is `Observable` and have property named 'abc' with value `number`.
619
+ * function f<O extends ObservableWithProperty<'abc', number>>( obj: O ) {}
620
+ * ```
621
+ */
622
+ export type ObservableWithProperty<
623
+ TKey extends PropertyKey,
624
+ TVal = any
625
+ > = undefined extends TVal ? Observable & { [P in TKey]?: TVal } : Observable & { [P in TKey]: TVal };
626
+ export interface ObservableDualBindChain<
627
+ TKey1 extends string,
628
+ TVal1,
629
+ TKey2 extends string,
630
+ TVal2
631
+ > {
632
+ to<
633
+ O extends ObservableWithProperty<K1, TVal1> & ObservableWithProperty<K2, TVal2>,
634
+ K1 extends keyof O,
635
+ K2 extends keyof O
636
+ >(observable: O, key1: K1, key2: K2): void;
637
+ to<O extends ObservableWithProperty<TKey1, TVal1> & ObservableWithProperty<TKey2, TVal2>>(observable: O): void;
556
638
  }
557
639
  export interface ObservableMultiBindChain {
558
- to<O extends Observable>(observable: O, ...properties: Array<keyof O>): void;
640
+ to<O extends Observable>(observable: O, ...properties: Array<keyof O>): void;
559
641
  }