UNPKG

25.7 kBTypeScriptView Raw
1// Type definitions for Backbone 1.4
2// Project: http://backbonejs.org/
3// https://github.com/jashkenas/backbone
4// Definitions by: Boris Yankov <https://github.com/borisyankov>
5// Natan Vivo <https://github.com/nvivo>
6// kenjiru <https://github.com/kenjiru>
7// jjoekoullas <https://github.com/jjoekoullas>
8// Julian Gonggrijp <https://github.com/jgonggrijp>
9// Kyle Scully <https://github.com/zieka>
10// Robert Kesterson <https://github.com/rkesters>
11// Bulat Khasanov <https://github.com/khasanovbi>
12// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
13// TypeScript Version: 2.8
14
15/// <reference types="jquery" />
16
17export = Backbone;
18export as namespace Backbone;
19
20import * as _ from 'underscore';
21
22declare namespace Backbone {
23 type _Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
24 type _Result<T> = T | (() => T);
25 type _StringKey<T> = keyof T & string;
26
27 interface AddOptions extends Silenceable {
28 at?: number | undefined;
29 merge?: boolean | undefined;
30 sort?: boolean | undefined;
31 }
32
33 interface CollectionSetOptions extends Parseable, Silenceable {
34 add?: boolean | undefined;
35 remove?: boolean | undefined;
36 merge?: boolean | undefined;
37 at?: number | undefined;
38 sort?: boolean | undefined;
39 }
40
41 interface HistoryOptions extends Silenceable {
42 pushState?: boolean | undefined;
43 root?: string | undefined;
44 hashChange?: boolean | undefined;
45 }
46
47 interface NavigateOptions {
48 trigger?: boolean | undefined;
49 replace?: boolean | undefined;
50 }
51
52 interface RouterOptions {
53 routes: _Result<RoutesHash>;
54 }
55
56 interface Silenceable {
57 silent?: boolean | undefined;
58 }
59
60 interface Validable {
61 validate?: boolean | undefined;
62 }
63
64 interface Waitable {
65 wait?: boolean | undefined;
66 }
67
68 interface Parseable {
69 parse?: boolean | undefined;
70 }
71
72 interface PersistenceOptions extends Partial<_Omit<JQueryAjaxSettings, 'success' | 'error'>> {
73 // TODO: Generalize modelOrCollection
74 success?: ((modelOrCollection: any, response: any, options: any) => void) | undefined;
75 error?: ((modelOrCollection: any, response: any, options: any) => void) | undefined;
76 emulateJSON?: boolean | undefined;
77 emulateHTTP?: boolean | undefined;
78 }
79
80 interface ModelConstructorOptions<TModel extends Model = Model> extends ModelSetOptions, Parseable {
81 collection?: Collection<TModel> | undefined;
82 }
83
84 type CombinedModelConstructorOptions<E, M extends Model<any, any, E> = Model> = ModelConstructorOptions<M> & E;
85
86 interface ModelSetOptions extends Silenceable, Validable {}
87
88 interface ModelFetchOptions extends PersistenceOptions, ModelSetOptions, Parseable {}
89
90 interface ModelSaveOptions extends Silenceable, Waitable, Validable, Parseable, PersistenceOptions {
91 patch?: boolean | undefined;
92 }
93
94 interface ModelDestroyOptions extends Waitable, PersistenceOptions {}
95
96 interface CollectionFetchOptions extends PersistenceOptions, Parseable, CollectionSetOptions {
97 reset?: boolean | undefined;
98 }
99
100 type ObjectHash = Record<string, any>;
101
102 interface RoutesHash {
103 [routePattern: string]: string | { (...urlParts: string[]): void };
104 }
105
106 /**
107 * DOM events (used in the events property of a View)
108 */
109 interface EventsHash {
110 [selector: string]: string | { (eventObject: JQuery.TriggeredEvent): void };
111 }
112
113 /**
114 * JavaScript events (used in the methods of the Events interface)
115 */
116 interface EventHandler {
117 (...args: any[]): void;
118 }
119 interface EventMap {
120 [event: string]: EventHandler;
121 }
122
123 const Events: Events;
124 interface Events extends EventsMixin {}
125
126 /**
127 * Helper shorthands for classes that implement the Events interface.
128 * Define your class like this:
129 *
130 * import {
131 * Events,
132 * Events_On,
133 * Events_Off,
134 * Events_Trigger,
135 * Events_Listen,
136 * Events_Stop,
137 * } from 'backbone';
138 *
139 * class YourClass implements Events {
140 * on: Events_On<YourClass>;
141 * off: Events_Off<YourClass>;
142 * trigger: Events_Trigger<YourClass>;
143 * bind: Events_On<YourClass>;
144 * unbind: Events_Off<YourClass>;
145 *
146 * once: Events_On<YourClass>;
147 * listenTo: Events_Listen<YourClass>;
148 * listenToOnce: Events_Listen<YourClass>;
149 * stopListening: Events_Stop<YourClass>;
150 *
151 * // ... (other methods)
152 * }
153 *
154 * Object.assign(YourClass.prototype, Events); // can also use _.extend
155 *
156 * If you are just writing a class type declaration that doesn't already
157 * extend some other base class, you can use the EventsMixin instead;
158 * see below.
159 */
160 interface Events_On<BaseT> {
161 <T extends BaseT>(this: T, eventName: string, callback: EventHandler, context?: any): T;
162 <T extends BaseT>(this: T, eventMap: EventMap, context?: any): T;
163 }
164 interface Events_Off<BaseT> {
165 <T extends BaseT>(this: T, eventName?: string | null, callback?: EventHandler | null, context?: any): T;
166 }
167 interface Events_Trigger<BaseT> {
168 <T extends BaseT>(this: T, eventName: string, ...args: any[]): T;
169 }
170 interface Events_Listen<BaseT> {
171 <T extends BaseT>(this: T, object: any, events: string, callback: EventHandler): T;
172 <T extends BaseT>(this: T, object: any, eventMap: EventMap): T;
173 }
174 interface Events_Stop<BaseT> {
175 <T extends BaseT>(this: T, object?: any, events?: string, callback?: EventHandler): T;
176 }
177
178 /**
179 * Helper to avoid code repetition in type declarations.
180 * Backbone.Events cannot be extended, hence a separate abstract
181 * class with a different name. Both classes and interfaces can
182 * extend from this helper class to reuse the signatures.
183 *
184 * For class type declarations that already extend another base
185 * class, and for actual class definitions, please see the
186 * Events_* interfaces above.
187 */
188 abstract class EventsMixin implements Events {
189 on(eventName: string, callback: EventHandler, context?: any): this;
190 on(eventMap: EventMap, context?: any): this;
191 off(eventName?: string | null, callback?: EventHandler | null, context?: any): this;
192 trigger(eventName: string, ...args: any[]): this;
193 bind(eventName: string, callback: EventHandler, context?: any): this;
194 bind(eventMap: EventMap, context?: any): this;
195 unbind(eventName?: string, callback?: EventHandler, context?: any): this;
196
197 once(events: string, callback: EventHandler, context?: any): this;
198 once(eventMap: EventMap, context?: any): this;
199 listenTo(object: any, events: string, callback: EventHandler): this;
200 listenTo(object: any, eventMap: EventMap): this;
201 listenToOnce(object: any, events: string, callback: EventHandler): this;
202 listenToOnce(object: any, eventMap: EventMap): this;
203 stopListening(object?: any, events?: string, callback?: EventHandler): this;
204 }
205
206 class ModelBase extends EventsMixin {
207 parse(response: any, options?: any): any;
208 toJSON(options?: any): any;
209 sync(...arg: any[]): JQueryXHR;
210 }
211
212 /**
213 * E - Extensions to the model constructor options. You can accept additional constructor options
214 * by listing them in the E parameter.
215 */
216 class Model<T extends ObjectHash = any, S = ModelSetOptions, E = any> extends ModelBase implements Events {
217 /**
218 * Do not use, prefer TypeScript's extend functionality.
219 */
220 static extend(properties: any, classProperties?: any): any;
221
222 attributes: Partial<T>;
223 changed: Partial<T>;
224 cidPrefix: string;
225 cid: string;
226 collection: Collection<this>;
227
228 private _changing: boolean;
229 private _previousAttributes: Partial<T>;
230 private _pending: boolean;
231
232 /**
233 * Default attributes for the model. It can be an object hash or a method returning an object hash.
234 * For assigning an object hash, do it like this: this.defaults = <any>{ attribute: value, ... };
235 * That works only if you set it in the constructor or the initialize method.
236 */
237 defaults(): Partial<T>;
238 id: string | number;
239 idAttribute: string;
240 validationError: any;
241
242 /**
243 * Returns the relative URL where the model's resource would be located on the server.
244 */
245 url: () => string;
246
247 urlRoot: _Result<string>;
248
249 /**
250 * For use with models as ES classes. If you define a preinitialize
251 * method, it will be invoked when the Model is first created, before
252 * any instantiation logic is run for the Model.
253 * @see https://backbonejs.org/#Model-preinitialize
254 */
255 preinitialize(attributes?: T, options?: CombinedModelConstructorOptions<E, this>): void;
256
257 constructor(attributes?: T, options?: CombinedModelConstructorOptions<E>);
258 initialize(attributes?: T, options?: CombinedModelConstructorOptions<E, this>): void;
259
260 fetch(options?: ModelFetchOptions): JQueryXHR;
261
262 /**
263 * For strongly-typed access to attributes, use the `get` method only privately in public getter properties.
264 * @example
265 * get name(): string {
266 * return super.get("name");
267 * }
268 */
269 get<A extends _StringKey<T>>(attributeName: A): T[A] | undefined;
270
271 /**
272 * For strongly-typed assignment of attributes, use the `set` method only privately in public setter properties.
273 * @example
274 * set name(value: string) {
275 * super.set("name", value);
276 * }
277 */
278 set<A extends _StringKey<T>>(attributeName: A, value?: T[A], options?: S): this;
279 set(attributeName: Partial<T>, options?: S): this;
280 set<A extends _StringKey<T>>(attributeName: A | Partial<T>, value?: T[A] | S, options?: S): this;
281
282 /**
283 * Return an object containing all the attributes that have changed, or
284 * false if there are no changed attributes. Useful for determining what
285 * parts of a view need to be updated and/or what attributes need to be
286 * persisted to the server. Unset attributes will be set to undefined.
287 * You can also pass an attributes object to diff against the model,
288 * determining if there *would be* a change.
289 */
290 changedAttributes(attributes?: Partial<T>): Partial<T> | false;
291 clear(options?: Silenceable): this;
292 clone(): Model;
293 destroy(options?: ModelDestroyOptions): JQueryXHR | false;
294 escape(attribute: _StringKey<T>): string;
295 has(attribute: _StringKey<T>): boolean;
296 hasChanged(attribute?: _StringKey<T>): boolean;
297 isNew(): boolean;
298 isValid(options?: any): boolean;
299 previous<A extends _StringKey<T>>(attribute: A): T[A] | null | undefined;
300 previousAttributes(): Partial<T>;
301 save(attributes?: Partial<T> | null, options?: ModelSaveOptions): JQueryXHR;
302 unset(attribute: _StringKey<T>, options?: Silenceable): this;
303 validate(attributes: Partial<T>, options?: any): any;
304 private _validate(attributes: Partial<T>, options: any): boolean;
305
306 // mixins from underscore
307
308 keys(): string[];
309 values(): any[];
310 pairs(): any[];
311 invert(): any;
312 pick<A extends _StringKey<T>>(keys: A[]): Partial<Pick<T, A>>;
313 pick<A extends _StringKey<T>>(...keys: A[]): Partial<Pick<T, A>>;
314 pick(fn: (value: any, key: any, object: any) => any): Partial<T>;
315 omit<A extends _StringKey<T>>(keys: A[]): Partial<_Omit<T, A>>;
316 omit<A extends _StringKey<T>>(...keys: A[]): Partial<_Omit<T, A>>;
317 omit(fn: (value: any, key: any, object: any) => any): Partial<T>;
318 chain(): any;
319 isEmpty(): boolean;
320 matches(attrs: any): boolean;
321 }
322
323 class Collection<TModel extends Model = Model> extends ModelBase implements Events {
324 /**
325 * Do not use, prefer TypeScript's extend functionality.
326 */
327 static extend(properties: any, classProperties?: any): any;
328
329 model: new (...args: any[]) => TModel;
330 models: TModel[];
331 length: number;
332
333 /**
334 * For use with collections as ES classes. If you define a preinitialize
335 * method, it will be invoked when the Collection is first created and
336 * before any instantiation logic is run for the Collection.
337 * @see https://backbonejs.org/#Collection-preinitialize
338 */
339 preinitialize(models?: TModel[] | Array<Record<string, any>>, options?: any): void;
340
341 constructor(models?: TModel[] | Array<Record<string, any>>, options?: any);
342 initialize(models?: TModel[] | Array<Record<string, any>>, options?: any): void;
343
344 fetch(options?: CollectionFetchOptions): JQueryXHR;
345
346 /**
347 * Specify a model attribute name (string) or function that will be used to sort the collection.
348 */
349 comparator:
350 | string
351 | { bivarianceHack(element: TModel): number | string }['bivarianceHack']
352 | { bivarianceHack(compare: TModel, to?: TModel): number }['bivarianceHack'];
353
354 add(model: {} | TModel, options?: AddOptions): TModel;
355 add(models: Array<{} | TModel>, options?: AddOptions): TModel[];
356 at(index: number): TModel;
357 /**
358 * Get a model from a collection, specified by an id, a cid, or by passing in a model.
359 */
360 get(id: number | string | Model): TModel;
361 has(key: number | string | Model): boolean;
362 clone(): this;
363 create(attributes: any, options?: ModelSaveOptions): TModel;
364 pluck(attribute: string): any[];
365 push(model: TModel, options?: AddOptions): TModel;
366 pop(options?: Silenceable): TModel;
367 remove(model: {} | TModel, options?: Silenceable): TModel;
368 remove(models: Array<{} | TModel>, options?: Silenceable): TModel[];
369 reset(models?: Array<{} | TModel>, options?: Silenceable): TModel[];
370
371 /**
372 *
373 * The set method performs a "smart" update of the collection with the passed list of models.
374 * If a model in the list isn't yet in the collection it will be added; if the model is already in the
375 * collection its attributes will be merged; and if the collection contains any models that aren't present
376 * in the list, they'll be removed. All of the appropriate "add", "remove", and "change" events are fired as
377 * this happens. Returns the touched models in the collection. If you'd like to customize the behavior, you can
378 * disable it with options: {add: false}, {remove: false}, or {merge: false}.
379 * @param models
380 * @param options
381 */
382 set(models?: Array<{} | TModel>, options?: CollectionSetOptions): TModel[];
383 shift(options?: Silenceable): TModel;
384 sort(options?: Silenceable): this;
385 unshift(model: TModel, options?: AddOptions): TModel;
386 where(properties: any): TModel[];
387 findWhere(properties: any): TModel;
388 modelId(attrs: any): any;
389
390 values(): Iterator<TModel>;
391 keys(): Iterator<any>;
392 entries(): Iterator<[any, TModel]>;
393 [Symbol.iterator](): Iterator<TModel>;
394
395 private _prepareModel(attributes?: any, options?: any): any;
396 private _removeReference(model: TModel): void;
397 private _onModelEvent(event: string, model: TModel, collection: Collection<TModel>, options: any): void;
398 private _isModel(obj: any): obj is Model;
399
400 /**
401 * Return a shallow copy of this collection's models, using the same options as native Array#slice.
402 */
403 slice(min?: number, max?: number): TModel[];
404
405 // mixins from underscore
406
407 all(iterator?: _.ListIterator<TModel, boolean>, context?: any): boolean;
408 any(iterator?: _.ListIterator<TModel, boolean>, context?: any): boolean;
409 chain(): any;
410 collect<TResult>(iterator: _.ListIterator<TModel, TResult>, context?: any): TResult[];
411 contains(value: TModel): boolean;
412 countBy(iterator?: _.ListIterator<TModel, any>): _.Dictionary<number>;
413 countBy(iterator: string): _.Dictionary<number>;
414 detect(iterator: _.ListIterator<TModel, boolean>, context?: any): TModel;
415 difference(others: TModel[]): TModel[];
416 drop(n?: number): TModel[];
417 each(iterator: _.ListIterator<TModel, void>, context?: any): TModel[];
418 every(iterator: _.ListIterator<TModel, boolean>, context?: any): boolean;
419 filter(iterator: _.ListIterator<TModel, boolean>, context?: any): TModel[];
420 find(iterator: _.ListIterator<TModel, boolean>, context?: any): TModel;
421 findIndex(predicate: _.ListIterator<TModel, boolean>, context?: any): number;
422 findLastIndex(predicate: _.ListIterator<TModel, boolean>, context?: any): number;
423 first(): TModel;
424 first(n: number): TModel[];
425 foldl<TResult>(iterator: _.MemoIterator<TModel, TResult>, memo?: TResult, context?: any): TResult;
426 foldr<TResult>(iterator: _.MemoIterator<TModel, TResult>, memo?: TResult, context?: any): TResult;
427 forEach(iterator: _.ListIterator<TModel, void>, context?: any): TModel[];
428 groupBy(iterator: _.ListIterator<TModel, any> | string, context?: any): _.Dictionary<TModel[]>;
429 head(): TModel;
430 head(n: number): TModel[];
431 include(value: TModel): boolean;
432 includes(value: TModel): boolean;
433 indexBy(iterator: _.ListIterator<TModel, any>, context?: any): _.Dictionary<TModel>;
434 indexBy(iterator: string, context?: any): _.Dictionary<TModel>;
435 indexOf(value: TModel, isSorted?: boolean): number;
436 initial(): TModel;
437 initial(n: number): TModel[];
438 inject<TResult>(iterator: _.MemoIterator<TModel, TResult>, memo?: TResult, context?: any): TResult;
439 invoke(methodName: string, ...args: any[]): any;
440 isEmpty(): boolean;
441 last(): TModel;
442 last(n: number): TModel[];
443 lastIndexOf(value: TModel, from?: number): number;
444 map<TResult>(iterator: _.ListIterator<TModel, TResult>, context?: any): TResult[];
445 max(iterator?: _.ListIterator<TModel, any>, context?: any): TModel;
446 min(iterator?: _.ListIterator<TModel, any>, context?: any): TModel;
447 partition(iterator: _.ListIterator<TModel, boolean>): TModel[][];
448 reduce<TResult>(iterator: _.MemoIterator<TModel, TResult>, memo?: TResult, context?: any): TResult;
449 reduceRight<TResult>(iterator: _.MemoIterator<TModel, TResult>, memo?: TResult, context?: any): TResult;
450 reject(iterator: _.ListIterator<TModel, boolean>, context?: any): TModel[];
451 rest(n?: number): TModel[];
452 sample(): TModel;
453 sample(n: number): TModel[];
454 select(iterator: _.ListIterator<TModel, boolean>, context?: any): TModel[];
455 shuffle(): TModel[];
456 size(): number;
457 some(iterator?: _.ListIterator<TModel, boolean>, context?: any): boolean;
458 sortBy(iterator?: _.ListIterator<TModel, any>, context?: any): TModel[];
459 sortBy(iterator: string, context?: any): TModel[];
460 tail(n?: number): TModel[];
461 take(): TModel;
462 take(n: number): TModel[];
463 toArray(): TModel[];
464
465 /**
466 * Sets the url property (or function) on a collection to reference its location on the server.
467 */
468 url: _Result<string>;
469
470 without(...values: TModel[]): TModel[];
471 }
472
473 type RouterCallback = (...args: string[]) => void;
474
475 class Router extends EventsMixin implements Events {
476 /**
477 * Do not use, prefer TypeScript's extend functionality.
478 */
479 static extend(properties: any, classProperties?: any): any;
480
481 /**
482 * Routes hash or a method returning the routes hash that maps URLs with parameters to methods on your Router.
483 * For assigning routes as object hash, do it like this: this.routes = <any>{ "route": callback, ... };
484 * That works only if you set it in the constructor or the initialize method.
485 */
486 routes: _Result<RoutesHash>;
487
488 /**
489 * For use with Router as ES classes. If you define a preinitialize method,
490 * it will be invoked when the Router is first created, before any
491 * instantiation logic is run for the Router.
492 * @see https://backbonejs.org/#Router-preinitialize
493 */
494 preinitialize(options?: RouterOptions): void;
495
496 constructor(options?: RouterOptions);
497 initialize(options?: RouterOptions): void;
498 route(route: string | RegExp, name: string, callback?: RouterCallback): this;
499 route(route: string | RegExp, callback: RouterCallback): this;
500 navigate(fragment: string, options?: NavigateOptions | boolean): this;
501
502 execute(callback: RouterCallback, args: string[], name: string): void;
503
504 protected _bindRoutes(): void;
505 protected _routeToRegExp(route: string): RegExp;
506 protected _extractParameters(route: RegExp, fragment: string): string[];
507 }
508
509 const history: History;
510
511 class History extends EventsMixin implements Events {
512 handlers: any[];
513 interval: number;
514
515 start(options?: HistoryOptions): boolean;
516
517 getHash(window?: Window): string;
518 getFragment(fragment?: string): string;
519 decodeFragment(fragment: string): string;
520 getSearch(): string;
521 stop(): void;
522 route(route: string | RegExp, callback: (fragment: string) => void): number;
523 checkUrl(e?: any): void;
524 getPath(): string;
525 matchRoot(): boolean;
526 atRoot(): boolean;
527 loadUrl(fragmentOverride?: string): boolean;
528 navigate(fragment: string, options?: any): boolean;
529 static started: boolean;
530 options: any;
531
532 private _updateHash(location: Location, fragment: string, replace: boolean): void;
533 }
534
535 interface ViewOptions<TModel extends (Model | undefined) = Model, TElement extends Element = HTMLElement> {
536 model?: TModel | undefined;
537 // TODO: quickfix, this can't be fixed easy. The collection does not need to have the same model as the parent view.
538 collection?: Collection<any> | undefined; // was: Collection<TModel>;
539 el?: TElement | JQuery | string | undefined;
540 id?: string | undefined;
541 attributes?: Record<string, any> | undefined;
542 className?: string | undefined;
543 tagName?: string | undefined;
544 events?: _Result<EventsHash> | undefined;
545 }
546
547 type ViewEventListener = (event: JQuery.Event) => void;
548
549 class View<TModel extends (Model | undefined) = Model, TElement extends Element = HTMLElement> extends EventsMixin implements Events {
550 /**
551 * Do not use, prefer TypeScript's extend functionality.
552 */
553 static extend(properties: any, classProperties?: any): any;
554
555 /**
556 * For use with views as ES classes. If you define a preinitialize
557 * method, it will be invoked when the view is first created, before any
558 * instantiation logic is run.
559 * @see https://backbonejs.org/#View-preinitialize
560 */
561 preinitialize(options?: ViewOptions<TModel, TElement>): void;
562
563 constructor(options?: ViewOptions<TModel, TElement>);
564 initialize(options?: ViewOptions<TModel, TElement>): void;
565
566 /**
567 * Events hash or a method returning the events hash that maps events/selectors to methods on your View.
568 * For assigning events as object hash, do it like this: this.events = <any>{ "event:selector": callback, ... };
569 * That works only if you set it in the constructor or the initialize method.
570 */
571 events(): EventsHash;
572
573 // A conditional type used here to prevent `TS2532: Object is possibly 'undefined'`
574 model: TModel extends Model ? TModel : undefined;
575 collection: Collection<any>;
576 setElement(element: TElement | JQuery): this;
577 id?: string | undefined;
578 cid: string;
579 className?: string | undefined;
580 tagName: string;
581
582 el: TElement;
583 $el: JQuery;
584 attributes: Record<string, any>;
585 $(selector: string): JQuery;
586 render(): this;
587 remove(): this;
588 delegateEvents(events?: _Result<EventsHash>): this;
589 delegate(eventName: string, selector: string, listener: ViewEventListener): this;
590 undelegateEvents(): this;
591 undelegate(eventName: string, selector?: string, listener?: ViewEventListener): this;
592
593 protected _removeElement(): void;
594 protected _setElement(el: TElement | JQuery): void;
595 protected _createElement(tagName: string): void;
596 protected _ensureElement(): void;
597 protected _setAttributes(attributes: Record<string, any>): void;
598 }
599
600 // SYNC
601 function sync(method: string, model: Model | Collection, options?: JQueryAjaxSettings): any;
602 function ajax(options?: JQueryAjaxSettings): JQueryXHR;
603 let emulateHTTP: boolean;
604 let emulateJSON: boolean;
605
606 // Utility
607 function noConflict(): typeof Backbone;
608 let $: JQueryStatic;
609}