UNPKG

27.3 kBTypeScriptView Raw
1declare module '@ember/runloop' {
2 import Backburner, { type Timer, type DeferredActionQueues } from 'backburner.js';
3 import type { AnyFn } from '@ember/-internals/utility-types';
4 export type { Timer };
5 type PartialParams<P extends any[]> = P extends [infer First, ...infer Rest]
6 ? [] | [First] | [First, ...PartialParams<Rest>]
7 : Required<P> extends [infer First, ...infer Rest]
8 ? [] | [First | undefined] | [First | undefined, ...PartialParams<Partial<Rest>>]
9 : [];
10 type RemainingParams<PartialParams extends any[], All extends any[]> = PartialParams extends [
11 infer First,
12 ...infer Rest
13 ]
14 ? All extends [infer AllFirst, ...infer AllRest]
15 ? First extends AllFirst
16 ? RemainingParams<Rest, AllRest>
17 : never
18 : Required<All> extends [infer AllFirst, ...infer AllRest]
19 ? First extends AllFirst | undefined
20 ? Partial<RemainingParams<Rest, AllRest>>
21 : never
22 : never
23 : PartialParams extends []
24 ? All
25 : never;
26 export function _getCurrentRunLoop(): DeferredActionQueues | null;
27 export const _rsvpErrorQueue: string;
28 /**
29 Array of named queues. This array determines the order in which queues
30 are flushed at the end of the RunLoop. You can define your own queues by
31 simply adding the queue name to this array. Normally you should not need
32 to inspect or modify this property.
33
34 @property queues
35 @type Array
36 @default ['actions', 'destroy']
37 @private
38 */
39 export const _queues: string[];
40 /**
41 * @internal
42 * @private
43 */
44 export const _backburner: Backburner;
45 /**
46 @module @ember/runloop
47 */
48 /**
49 Runs the passed target and method inside of a RunLoop, ensuring any
50 deferred actions including bindings and views updates are flushed at the
51 end.
52
53 Normally you should not need to invoke this method yourself. However if
54 you are implementing raw event handlers when interfacing with other
55 libraries or plugins, you should probably wrap all of your code inside this
56 call.
57
58 ```javascript
59 import { run } from '@ember/runloop';
60
61 run(function() {
62 // code to be executed within a RunLoop
63 });
64 ```
65 @method run
66 @for @ember/runloop
67 @static
68 @param {Object} [target] target of method to call
69 @param {Function|String} method Method to invoke.
70 May be a function or a string. If you pass a string
71 then it will be looked up on the passed target.
72 @param {Object} [args*] Any additional arguments you wish to pass to the method.
73 @return {Object} return value from invoking the passed function.
74 @public
75 */
76 export function run<F extends () => any>(method: F): ReturnType<F>;
77 export function run<F extends AnyFn>(method: F, ...args: Parameters<F>): ReturnType<F>;
78 export function run<T, F extends (this: T, ...args: any[]) => any>(
79 target: T,
80 method: F,
81 ...args: Parameters<F>
82 ): ReturnType<F>;
83 export function run<T, U extends keyof T>(
84 target: T,
85 method: U,
86 ...args: T[U] extends AnyFn ? Parameters<T[U]> : []
87 ): T[U] extends AnyFn ? ReturnType<T[U]> : unknown;
88 /**
89 If no run-loop is present, it creates a new one. If a run loop is
90 present it will queue itself to run on the existing run-loops action
91 queue.
92
93 Please note: This is not for normal usage, and should be used sparingly.
94
95 If invoked when not within a run loop:
96
97 ```javascript
98 import { join } from '@ember/runloop';
99
100 join(function() {
101 // creates a new run-loop
102 });
103 ```
104
105 Alternatively, if called within an existing run loop:
106
107 ```javascript
108 import { run, join } from '@ember/runloop';
109
110 run(function() {
111 // creates a new run-loop
112
113 join(function() {
114 // joins with the existing run-loop, and queues for invocation on
115 // the existing run-loops action queue.
116 });
117 });
118 ```
119
120 @method join
121 @static
122 @for @ember/runloop
123 @param {Object} [target] target of method to call
124 @param {Function|String} method Method to invoke.
125 May be a function or a string. If you pass a string
126 then it will be looked up on the passed target.
127 @param {Object} [args*] Any additional arguments you wish to pass to the method.
128 @return {Object} Return value from invoking the passed function. Please note,
129 when called within an existing loop, no return value is possible.
130 @public
131 */
132 export function join<F extends AnyFn>(method: F, ...args: Parameters<F>): ReturnType<F> | void;
133 export function join<T, F extends (this: T, ...args: any[]) => any>(
134 target: T,
135 method: F,
136 ...args: Parameters<F>
137 ): ReturnType<F> | void;
138 export function join<T, U extends keyof T>(
139 target: T,
140 method: U,
141 ...args: T[U] extends AnyFn ? Parameters<T[U]> : []
142 ): T[U] extends AnyFn ? ReturnType<T[U]> | void : void;
143 /**
144 Allows you to specify which context to call the specified function in while
145 adding the execution of that function to the Ember run loop. This ability
146 makes this method a great way to asynchronously integrate third-party libraries
147 into your Ember application.
148
149 `bind` takes two main arguments, the desired context and the function to
150 invoke in that context. Any additional arguments will be supplied as arguments
151 to the function that is passed in.
152
153 Let's use the creation of a TinyMCE component as an example. Currently,
154 TinyMCE provides a setup configuration option we can use to do some processing
155 after the TinyMCE instance is initialized but before it is actually rendered.
156 We can use that setup option to do some additional setup for our component.
157 The component itself could look something like the following:
158
159 ```app/components/rich-text-editor.js
160 import Component from '@ember/component';
161 import { on } from '@ember/object/evented';
162 import { bind } from '@ember/runloop';
163
164 export default Component.extend({
165 initializeTinyMCE: on('didInsertElement', function() {
166 tinymce.init({
167 selector: '#' + this.$().prop('id'),
168 setup: bind(this, this.setupEditor)
169 });
170 }),
171
172 didInsertElement() {
173 tinymce.init({
174 selector: '#' + this.$().prop('id'),
175 setup: bind(this, this.setupEditor)
176 });
177 }
178
179 setupEditor(editor) {
180 this.set('editor', editor);
181
182 editor.on('change', function() {
183 console.log('content changed!');
184 });
185 }
186 });
187 ```
188
189 In this example, we use `bind` to bind the setupEditor method to the
190 context of the RichTextEditor component and to have the invocation of that
191 method be safely handled and executed by the Ember run loop.
192
193 @method bind
194 @static
195 @for @ember/runloop
196 @param {Object} [target] target of method to call
197 @param {Function|String} method Method to invoke.
198 May be a function or a string. If you pass a string
199 then it will be looked up on the passed target.
200 @param {Object} [args*] Any additional arguments you wish to pass to the method.
201 @return {Function} returns a new function that will always have a particular context
202 @since 1.4.0
203 @public
204 */
205 export function bind<
206 T,
207 F extends (this: T, ...args: any[]) => any,
208 A extends PartialParams<Parameters<F>>
209 >(
210 target: T,
211 method: F,
212 ...args: A
213 ): (...args: RemainingParams<A, Parameters<F>>) => ReturnType<F> | void;
214 export function bind<F extends AnyFn, A extends PartialParams<Parameters<F>>>(
215 method: F,
216 ...args: A
217 ): (...args: RemainingParams<A, Parameters<F>>) => ReturnType<F> | void;
218 export function bind<
219 T,
220 U extends keyof T,
221 A extends T[U] extends AnyFn ? PartialParams<Parameters<T[U]>> : []
222 >(
223 target: T,
224 method: U,
225 ...args: A
226 ): T[U] extends AnyFn
227 ? (...args: RemainingParams<A, Parameters<T[U]>>) => ReturnType<T[U]> | void
228 : never;
229 export function bind<T, M extends keyof T & PropertyKey>(
230 target: T,
231 methodName: M,
232 ...args: any[]
233 ): (...args: any[]) => unknown;
234 /**
235 Begins a new RunLoop. Any deferred actions invoked after the begin will
236 be buffered until you invoke a matching call to `end()`. This is
237 a lower-level way to use a RunLoop instead of using `run()`.
238
239 ```javascript
240 import { begin, end } from '@ember/runloop';
241
242 begin();
243 // code to be executed within a RunLoop
244 end();
245 ```
246
247 @method begin
248 @static
249 @for @ember/runloop
250 @return {void}
251 @public
252 */
253 export function begin(): void;
254 /**
255 Ends a RunLoop. This must be called sometime after you call
256 `begin()` to flush any deferred actions. This is a lower-level way
257 to use a RunLoop instead of using `run()`.
258
259 ```javascript
260 import { begin, end } from '@ember/runloop';
261
262 begin();
263 // code to be executed within a RunLoop
264 end();
265 ```
266
267 @method end
268 @static
269 @for @ember/runloop
270 @return {void}
271 @public
272 */
273 export function end(): void;
274 /**
275 Adds the passed target/method and any optional arguments to the named
276 queue to be executed at the end of the RunLoop. If you have not already
277 started a RunLoop when calling this method one will be started for you
278 automatically.
279
280 At the end of a RunLoop, any methods scheduled in this way will be invoked.
281 Methods will be invoked in an order matching the named queues defined in
282 the `queues` property.
283
284 ```javascript
285 import { schedule } from '@ember/runloop';
286
287 schedule('afterRender', this, function() {
288 // this will be executed in the 'afterRender' queue
289 console.log('scheduled on afterRender queue');
290 });
291
292 schedule('actions', this, function() {
293 // this will be executed in the 'actions' queue
294 console.log('scheduled on actions queue');
295 });
296
297 // Note the functions will be run in order based on the run queues order.
298 // Output would be:
299 // scheduled on actions queue
300 // scheduled on afterRender queue
301 ```
302
303 @method schedule
304 @static
305 @for @ember/runloop
306 @param {String} queue The name of the queue to schedule against. Default queues is 'actions'
307 @param {Object} [target] target object to use as the context when invoking a method.
308 @param {String|Function} method The method to invoke. If you pass a string it
309 will be resolved on the target object at the time the scheduled item is
310 invoked allowing you to change the target function.
311 @param {Object} [arguments*] Optional arguments to be passed to the queued method.
312 @return {*} Timer information for use in canceling, see `cancel`.
313 @public
314 */
315 export function schedule<F extends AnyFn>(
316 queueName: string,
317 method: F,
318 ...args: Parameters<F>
319 ): Timer;
320 export function schedule<T, F extends (this: T, ...args: any[]) => any>(
321 queueName: string,
322 target: T,
323 method: F,
324 ...args: Parameters<F>
325 ): Timer;
326 export function schedule<T, U extends keyof T>(
327 queueName: string,
328 target: T,
329 method: U,
330 ...args: T[U] extends AnyFn ? Parameters<T[U]> : []
331 ): Timer;
332 export function _hasScheduledTimers(): boolean;
333 export function _cancelTimers(): void;
334 /**
335 Invokes the passed target/method and optional arguments after a specified
336 period of time. The last parameter of this method must always be a number
337 of milliseconds.
338
339 You should use this method whenever you need to run some action after a
340 period of time instead of using `setTimeout()`. This method will ensure that
341 items that expire during the same script execution cycle all execute
342 together, which is often more efficient than using a real setTimeout.
343
344 ```javascript
345 import { later } from '@ember/runloop';
346
347 later(myContext, function() {
348 // code here will execute within a RunLoop in about 500ms with this == myContext
349 }, 500);
350 ```
351
352 @method later
353 @static
354 @for @ember/runloop
355 @param {Object} [target] target of method to invoke
356 @param {Function|String} method The method to invoke.
357 If you pass a string it will be resolved on the
358 target at the time the method is invoked.
359 @param {Object} [args*] Optional arguments to pass to the timeout.
360 @param {Number} wait Number of milliseconds to wait.
361 @return {*} Timer information for use in canceling, see `cancel`.
362 @public
363 */
364 export function later<T, F extends (this: T, ...args: any[]) => any>(
365 target: T,
366 method: F,
367 ...args: [...args: Parameters<F>, wait: string | number]
368 ): Timer;
369 export function later<F extends AnyFn>(
370 method: F,
371 ...args: [...args: Parameters<F>, wait: string | number]
372 ): Timer;
373 export function later<T, U extends keyof T>(
374 target: T,
375 method: U,
376 ...args: [...args: T[U] extends AnyFn ? Parameters<T[U]> : [], wait: string | number]
377 ): Timer;
378 /**
379 Schedule a function to run one time during the current RunLoop. This is equivalent
380 to calling `scheduleOnce` with the "actions" queue.
381
382 @method once
383 @static
384 @for @ember/runloop
385 @param {Object} [target] The target of the method to invoke.
386 @param {Function|String} method The method to invoke.
387 If you pass a string it will be resolved on the
388 target at the time the method is invoked.
389 @param {Object} [args*] Optional arguments to pass to the timeout.
390 @return {Object} Timer information for use in canceling, see `cancel`.
391 @public
392 */
393 export function once<F extends AnyFn>(method: F, ...args: Parameters<F>): Timer;
394 export function once<T, F extends (this: T, ...args: any[]) => any>(
395 target: T,
396 method: F,
397 ...args: Parameters<F>
398 ): Timer;
399 export function once<T, U extends keyof T>(
400 target: T,
401 method: U,
402 ...args: T[U] extends AnyFn ? Parameters<T[U]> : []
403 ): Timer;
404 /**
405 Schedules a function to run one time in a given queue of the current RunLoop.
406 Calling this method with the same queue/target/method combination will have
407 no effect (past the initial call).
408
409 Note that although you can pass optional arguments these will not be
410 considered when looking for duplicates. New arguments will replace previous
411 calls.
412
413 ```javascript
414 import { run, scheduleOnce } from '@ember/runloop';
415
416 function sayHi() {
417 console.log('hi');
418 }
419
420 run(function() {
421 scheduleOnce('afterRender', myContext, sayHi);
422 scheduleOnce('afterRender', myContext, sayHi);
423 // sayHi will only be executed once, in the afterRender queue of the RunLoop
424 });
425 ```
426
427 Also note that for `scheduleOnce` to prevent additional calls, you need to
428 pass the same function instance. The following case works as expected:
429
430 ```javascript
431 function log() {
432 console.log('Logging only once');
433 }
434
435 function scheduleIt() {
436 scheduleOnce('actions', myContext, log);
437 }
438
439 scheduleIt();
440 scheduleIt();
441 ```
442
443 But this other case will schedule the function multiple times:
444
445 ```javascript
446 import { scheduleOnce } from '@ember/runloop';
447
448 function scheduleIt() {
449 scheduleOnce('actions', myContext, function() {
450 console.log('Closure');
451 });
452 }
453
454 scheduleIt();
455 scheduleIt();
456
457 // "Closure" will print twice, even though we're using `scheduleOnce`,
458 // because the function we pass to it won't match the
459 // previously scheduled operation.
460 ```
461
462 Available queues, and their order, can be found at `queues`
463
464 @method scheduleOnce
465 @static
466 @for @ember/runloop
467 @param {String} [queue] The name of the queue to schedule against. Default queues is 'actions'.
468 @param {Object} [target] The target of the method to invoke.
469 @param {Function|String} method The method to invoke.
470 If you pass a string it will be resolved on the
471 target at the time the method is invoked.
472 @param {Object} [args*] Optional arguments to pass to the timeout.
473 @return {Object} Timer information for use in canceling, see `cancel`.
474 @public
475 */
476 export function scheduleOnce<F extends AnyFn>(
477 queueName: string,
478 method: F,
479 ...args: Parameters<F>
480 ): Timer;
481 export function scheduleOnce<T, F extends (this: T, ...args: any[]) => any>(
482 queueName: string,
483 target: T,
484 method: F,
485 ...args: Parameters<F>
486 ): Timer;
487 export function scheduleOnce<T, U extends keyof T>(
488 queueName: string,
489 target: T,
490 method: U,
491 ...args: T[U] extends AnyFn ? Parameters<T[U]> : []
492 ): Timer;
493 /**
494 Schedules an item to run from within a separate run loop, after
495 control has been returned to the system. This is equivalent to calling
496 `later` with a wait time of 1ms.
497
498 ```javascript
499 import { next } from '@ember/runloop';
500
501 next(myContext, function() {
502 // code to be executed in the next run loop,
503 // which will be scheduled after the current one
504 });
505 ```
506
507 Multiple operations scheduled with `next` will coalesce
508 into the same later run loop, along with any other operations
509 scheduled by `later` that expire right around the same
510 time that `next` operations will fire.
511
512 Note that there are often alternatives to using `next`.
513 For instance, if you'd like to schedule an operation to happen
514 after all DOM element operations have completed within the current
515 run loop, you can make use of the `afterRender` run loop queue (added
516 by the `ember-views` package, along with the preceding `render` queue
517 where all the DOM element operations happen).
518
519 Example:
520
521 ```app/components/my-component.js
522 import Component from '@ember/component';
523 import { scheduleOnce } from '@ember/runloop';
524
525 export Component.extend({
526 didInsertElement() {
527 this._super(...arguments);
528 scheduleOnce('afterRender', this, 'processChildElements');
529 },
530
531 processChildElements() {
532 // ... do something with component's child component
533 // elements after they've finished rendering, which
534 // can't be done within this component's
535 // `didInsertElement` hook because that gets run
536 // before the child elements have been added to the DOM.
537 }
538 });
539 ```
540
541 One benefit of the above approach compared to using `next` is
542 that you will be able to perform DOM/CSS operations before unprocessed
543 elements are rendered to the screen, which may prevent flickering or
544 other artifacts caused by delaying processing until after rendering.
545
546 The other major benefit to the above approach is that `next`
547 introduces an element of non-determinism, which can make things much
548 harder to test, due to its reliance on `setTimeout`; it's much harder
549 to guarantee the order of scheduled operations when they are scheduled
550 outside of the current run loop, i.e. with `next`.
551
552 @method next
553 @static
554 @for @ember/runloop
555 @param {Object} [target] target of method to invoke
556 @param {Function|String} method The method to invoke.
557 If you pass a string it will be resolved on the
558 target at the time the method is invoked.
559 @param {Object} [args*] Optional arguments to pass to the timeout.
560 @return {Object} Timer information for use in canceling, see `cancel`.
561 @public
562 */
563 export function next<F extends AnyFn>(method: F, ...args: Parameters<F>): Timer;
564 export function next<T, F extends (this: T, ...args: any[]) => any>(
565 target: T,
566 method: F,
567 ...args: Parameters<F>
568 ): Timer;
569 export function next<T, U extends keyof T>(
570 target: T,
571 method: U,
572 ...args: T[U] extends AnyFn ? Parameters<T[U]> : []
573 ): Timer;
574 /**
575 Cancels a scheduled item. Must be a value returned by `later()`,
576 `once()`, `scheduleOnce()`, `next()`, `debounce()`, or
577 `throttle()`.
578
579 ```javascript
580 import {
581 next,
582 cancel,
583 later,
584 scheduleOnce,
585 once,
586 throttle,
587 debounce
588 } from '@ember/runloop';
589
590 let runNext = next(myContext, function() {
591 // will not be executed
592 });
593
594 cancel(runNext);
595
596 let runLater = later(myContext, function() {
597 // will not be executed
598 }, 500);
599
600 cancel(runLater);
601
602 let runScheduleOnce = scheduleOnce('afterRender', myContext, function() {
603 // will not be executed
604 });
605
606 cancel(runScheduleOnce);
607
608 let runOnce = once(myContext, function() {
609 // will not be executed
610 });
611
612 cancel(runOnce);
613
614 let throttle = throttle(myContext, function() {
615 // will not be executed
616 }, 1, false);
617
618 cancel(throttle);
619
620 let debounce = debounce(myContext, function() {
621 // will not be executed
622 }, 1);
623
624 cancel(debounce);
625
626 let debounceImmediate = debounce(myContext, function() {
627 // will be executed since we passed in true (immediate)
628 }, 100, true);
629
630 // the 100ms delay until this method can be called again will be canceled
631 cancel(debounceImmediate);
632 ```
633
634 @method cancel
635 @static
636 @for @ember/runloop
637 @param {Object} [timer] Timer object to cancel
638 @return {Boolean} true if canceled or false/undefined if it wasn't found
639 @public
640 */
641 export function cancel(timer?: Timer): boolean;
642 /**
643 Delay calling the target method until the debounce period has elapsed
644 with no additional debounce calls. If `debounce` is called again before
645 the specified time has elapsed, the timer is reset and the entire period
646 must pass again before the target method is called.
647
648 This method should be used when an event may be called multiple times
649 but the action should only be called once when the event is done firing.
650 A common example is for scroll events where you only want updates to
651 happen once scrolling has ceased.
652
653 ```javascript
654 import { debounce } from '@ember/runloop';
655
656 function whoRan() {
657 console.log(this.name + ' ran.');
658 }
659
660 let myContext = { name: 'debounce' };
661
662 debounce(myContext, whoRan, 150);
663
664 // less than 150ms passes
665 debounce(myContext, whoRan, 150);
666
667 // 150ms passes
668 // whoRan is invoked with context myContext
669 // console logs 'debounce ran.' one time.
670 ```
671
672 Immediate allows you to run the function immediately, but debounce
673 other calls for this function until the wait time has elapsed. If
674 `debounce` is called again before the specified time has elapsed,
675 the timer is reset and the entire period must pass again before
676 the method can be called again.
677
678 ```javascript
679 import { debounce } from '@ember/runloop';
680
681 function whoRan() {
682 console.log(this.name + ' ran.');
683 }
684
685 let myContext = { name: 'debounce' };
686
687 debounce(myContext, whoRan, 150, true);
688
689 // console logs 'debounce ran.' one time immediately.
690 // 100ms passes
691 debounce(myContext, whoRan, 150, true);
692
693 // 150ms passes and nothing else is logged to the console and
694 // the debouncee is no longer being watched
695 debounce(myContext, whoRan, 150, true);
696
697 // console logs 'debounce ran.' one time immediately.
698 // 150ms passes and nothing else is logged to the console and
699 // the debouncee is no longer being watched
700 ```
701
702 @method debounce
703 @static
704 @for @ember/runloop
705 @param {Object} [target] target of method to invoke
706 @param {Function|String} method The method to invoke.
707 May be a function or a string. If you pass a string
708 then it will be looked up on the passed target.
709 @param {Object} [args*] Optional arguments to pass to the timeout.
710 @param {Number} wait Number of milliseconds to wait.
711 @param {Boolean} immediate Trigger the function on the leading instead
712 of the trailing edge of the wait interval. Defaults to false.
713 @return {Array} Timer information for use in canceling, see `cancel`.
714 @public
715 */
716 export function debounce<F extends AnyFn>(
717 method: F,
718 ...args: [...args: Parameters<F>, wait: string | number, immediate?: boolean]
719 ): Timer;
720 export function debounce<T, F extends (this: T, ...args: any[]) => any>(
721 target: T,
722 method: F,
723 ...args: [...args: Parameters<F>, wait: string | number, immediate?: boolean]
724 ): Timer;
725 export function debounce<T, U extends keyof T>(
726 target: T,
727 method: U,
728 ...args: [
729 ...args: T[U] extends AnyFn ? Parameters<T[U]> : [],
730 wait: string | number,
731 immediate?: boolean
732 ]
733 ): Timer;
734 /**
735 Ensure that the target method is never called more frequently than
736 the specified spacing period. The target method is called immediately.
737
738 ```javascript
739 import { throttle } from '@ember/runloop';
740
741 function whoRan() {
742 console.log(this.name + ' ran.');
743 }
744
745 let myContext = { name: 'throttle' };
746
747 throttle(myContext, whoRan, 150);
748 // whoRan is invoked with context myContext
749 // console logs 'throttle ran.'
750
751 // 50ms passes
752 throttle(myContext, whoRan, 150);
753
754 // 50ms passes
755 throttle(myContext, whoRan, 150);
756
757 // 150ms passes
758 throttle(myContext, whoRan, 150);
759 // whoRan is invoked with context myContext
760 // console logs 'throttle ran.'
761 ```
762
763 @method throttle
764 @static
765 @for @ember/runloop
766 @param {Object} [target] target of method to invoke
767 @param {Function|String} method The method to invoke.
768 May be a function or a string. If you pass a string
769 then it will be looked up on the passed target.
770 @param {Object} [args*] Optional arguments to pass to the timeout.
771 @param {Number} spacing Number of milliseconds to space out requests.
772 @param {Boolean} immediate Trigger the function on the leading instead
773 of the trailing edge of the wait interval. Defaults to true.
774 @return {Array} Timer information for use in canceling, see `cancel`.
775 @public
776 */
777 export function throttle<F extends AnyFn>(
778 method: F,
779 ...args: [...args: Parameters<F>, wait?: string | number, immediate?: boolean]
780 ): Timer;
781 export function throttle<T, F extends (this: T, ...args: any[]) => any>(
782 target: T,
783 method: F,
784 ...args: [...args: Parameters<F>, wait?: string | number, immediate?: boolean]
785 ): Timer;
786 export function throttle<T, U extends keyof T>(
787 target: T,
788 method: U,
789 ...args: [
790 ...args: T[U] extends AnyFn ? Parameters<T[U]> : [],
791 wait?: string | number,
792 immediate?: boolean
793 ]
794 ): Timer;
795}