• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// @Filename: underscoreTest1_underscore.ts
2interface Dictionary<T> {
3    [x: string]: T;
4}
5
6interface Iterator_<T, U> {
7    (value: T, index: any, list: any): U;
8}
9
10interface Reducer<T, U> {
11    (accumulator: U, value: T, index: any, list: any): U;
12}
13
14interface Tuple2<T0, T1> extends Array<any> {
15    0: T0;
16    1: T1;
17}
18
19interface Tuple3<T0, T1, T2> extends Array<any> {
20    0: T0;
21    1: T1;
22    2: T2;
23}
24
25interface Tuple4<T0, T1, T2, T3> extends Array<any> {
26    0: T0;
27    1: T1;
28    2: T2;
29    3: T3;
30}
31
32module Underscore {
33    export interface WrappedObject<T> {
34        keys(): string[];
35        values(): any[];
36        pairs(): any[][];
37        invert(): any;
38        functions(): string[];
39        methods(): string[];
40        extend(...sources: any[]): T;
41        pick(...keys: string[]): T;
42        omit(...keys: string[]): T;
43        defaults(...defaults: any[]): T;
44        clone(): T;
45        tap(interceptor: (object: T) => void): T;
46        has(key: string): boolean;
47        isEqual(other: T): boolean;
48        isEmpty(): boolean;
49        isElement(): boolean;
50        isArray(): boolean;
51        isObject(): boolean;
52        isArguments(): boolean;
53        isFunction(): boolean;
54        isString(): boolean;
55        isNumber(): boolean;
56        isFinite(): boolean;
57        isBoolean(): boolean;
58        isDate(): boolean;
59        isRegExp(): boolean;
60        isNaN(): boolean;
61        isNull(): boolean;
62        isUndefined(): boolean;
63        value(): T;
64    }
65
66    export interface WrappedFunction<T extends Function> extends WrappedObject<T> {
67        bind(object: any): T;
68        bind(object: any, ...args: any[]): Function;
69        bindAll(...methodNames: string[]): T;
70        partial(...args: any[]): Function;
71        memoize(hashFunction?: Function): T;
72        delay(wait: number, ...args: any[]): number;
73        defer(...args: any[]): number;
74        throttle(wait: number): T;
75        debounce(wait: number, immediate?: boolean): T;
76        once(): T;
77        wrap(wrapper: (func: T, ...args: any[]) => any): T;
78        compose(...funcs: Function[]): Function;
79    }
80
81    export interface WrappedArray<T> extends WrappedObject<Array<T>> {
82        each(iterator: Iterator_<T, void>, context?: any): void;
83        forEach(iterator: Iterator_<T, void>, context?: any): void;
84        map<U>(iterator: Iterator_<T, U>, context?: any): U[];
85        collect<U>(iterator: Iterator_<T, U>, context?: any): U[];
86        reduce(iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
87        reduce<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): U;
88        foldl(iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
89        foldl<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): U;
90        inject(iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
91        inject<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): U;
92        reduceRight(iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
93        reduceRight<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): U;
94        foldr(iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
95        foldr<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): U;
96        find(iterator: Iterator_<T, boolean>, context?: any): T;
97        detect(iterator: Iterator_<T, boolean>, context?: any): T;
98        filter(iterator: Iterator_<T, boolean>, context?: any): T[];
99        select(iterator: Iterator_<T, boolean>, context?: any): T[];
100        where(properties: Object): T[];
101        findWhere(properties: Object): T;
102        reject(iterator: Iterator_<T, boolean>, context?: any): T[];
103        every(iterator?: Iterator_<T, boolean>, context?: any): boolean;
104        all(iterator?: Iterator_<T, boolean>, context?: any): boolean;
105        some(iterator?: Iterator_<T, boolean>, context?: any): boolean;
106        any(iterator?: Iterator_<T, boolean>, context?: any): boolean;
107        contains(value: T): boolean;
108        include(value: T): boolean;
109        invoke(methodName: string, ...args: any[]): any[];
110        pluck(propertyName: string): any[];
111        max(iterator?: Iterator_<T, any>, context?: any): T;
112        min(iterator?: Iterator_<T, any>, context?: any): T;
113        sortBy(iterator: Iterator_<T, any>, context?: any): T[];
114        sortBy(propertyName: string): T[];
115        groupBy(iterator?: Iterator_<T, any>, context?: any): Dictionary<T[]>;
116        groupBy(propertyName: string): Dictionary<T[]>;
117        countBy(iterator?: Iterator_<T, any>, context?: any): Dictionary<number>;
118        countBy(propertyName: string): Dictionary<number>;
119        shuffle(): T[];
120        toArray(): T[];
121        size(): number;
122        first(): T;
123        first(count: number): T[];
124        head(): T;
125        head(count: number): T[];
126        take(): T;
127        take(count: number): T[];
128        initial(): T;
129        initial(count: number): T[];
130        last(): T;
131        last(count: number): T[];
132        rest(index?: number): T[];
133        compact(): T[];
134        flatten<U>(shallow?: boolean): U[];
135        without(...values: T[]): T[];
136        union(...arrays: T[][]): T[];
137        intersection(...arrays: T[][]): T[];
138        difference(...others: T[][]): T[];
139        uniq(isSorted?: boolean): T[];
140        uniq<U>(isSorted: boolean, iterator: Iterator_<T, U>, context?: any): U[];
141        unique(isSorted?: boolean): T[];
142        unique<U>(isSorted: boolean, iterator: Iterator_<T, U>, context?: any): U[];
143        zip(...arrays: any[][]): any[][];
144        object(): any;
145        object(values: any[]): any;
146        indexOf(value: T, isSorted?: boolean): number;
147        lastIndexOf(value: T, fromIndex?: number): number;
148        sortedIndex(obj: T, propertyName: string): number;
149        sortedIndex(obj: T, iterator?: Iterator_<T, any>, context?: any): number;
150        // Methods from Array
151        concat(...items: T[]): T[];
152        join(separator?: string): string;
153        pop(): T;
154        push(...items: T[]): number;
155        reverse(): T[];
156        shift(): T;
157        slice(start: number, end?: number): T[];
158        sort(compareFn?: (a: T, b: T) => number): T[];
159        splice(start: number): T[];
160        splice(start: number, deleteCount: number, ...items: T[]): T[];
161        unshift(...items: T[]): number;
162    }
163
164    export interface WrappedDictionary<T> extends WrappedObject<Dictionary<T>> {
165        each(iterator: Iterator_<T, void>, context?: any): void;
166        forEach(iterator: Iterator_<T, void>, context?: any): void;
167        map<U>(iterator: Iterator_<T, U>, context?: any): U[];
168        collect<U>(iterator: Iterator_<T, U>, context?: any): U[];
169        reduce(iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
170        reduce<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): U;
171        foldl(iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
172        foldl<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): U;
173        inject(iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
174        inject<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): U;
175        reduceRight(iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
176        reduceRight<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): U;
177        foldr(iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
178        foldr<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): U;
179        find(iterator: Iterator_<T, boolean>, context?: any): T;
180        detect(iterator: Iterator_<T, boolean>, context?: any): T;
181        filter(iterator: Iterator_<T, boolean>, context?: any): T[];
182        select(iterator: Iterator_<T, boolean>, context?: any): T[];
183        where(properties: Object): T[];
184        findWhere(properties: Object): T;
185        reject(iterator: Iterator_<T, boolean>, context?: any): T[];
186        every(iterator?: Iterator_<T, boolean>, context?: any): boolean;
187        all(iterator?: Iterator_<T, boolean>, context?: any): boolean;
188        some(iterator?: Iterator_<T, boolean>, context?: any): boolean;
189        any(iterator?: Iterator_<T, boolean>, context?: any): boolean;
190        contains(value: T): boolean;
191        include(value: T): boolean;
192        invoke(methodName: string, ...args: any[]): any[];
193        pluck(propertyName: string): any[];
194        max(iterator?: Iterator_<T, any>, context?: any): T;
195        min(iterator?: Iterator_<T, any>, context?: any): T;
196        sortBy(iterator: Iterator_<T, any>, context?: any): T[];
197        sortBy(propertyName: string): T[];
198        groupBy(iterator?: Iterator_<T, any>, context?: any): Dictionary<T[]>;
199        groupBy(propertyName: string): Dictionary<T[]>;
200        countBy(iterator?: Iterator_<T, any>, context?: any): Dictionary<number>;
201        countBy(propertyName: string): Dictionary<number>;
202        shuffle(): T[];
203        toArray(): T[];
204        size(): number;
205    }
206
207    export interface ChainedObject<T> {
208        keys(): ChainedArray<string>;
209        values(): ChainedArray<any>;
210        pairs(): ChainedArray<any[]>;
211        invert(): ChainedObject<any>;
212        functions(): ChainedArray<string>;
213        methods(): ChainedArray<string>;
214        extend(...sources: any[]): ChainedObject<T>;
215        pick(...keys: string[]): ChainedObject<T>;
216        omit(...keys: string[]): ChainedObject<T>;
217        defaults(...defaults: any[]): ChainedObject<T>;
218        clone(): ChainedObject<T>;
219        tap(interceptor: (object: T) => void): ChainedObject<T>;
220        has(key: string): ChainedObject<boolean>;
221        isEqual(other: T): ChainedObject<boolean>;
222        isEmpty(): ChainedObject<boolean>;
223        isElement(): ChainedObject<boolean>;
224        isArray(): ChainedObject<boolean>;
225        isObject(): ChainedObject<boolean>;
226        isArguments(): ChainedObject<boolean>;
227        isFunction(): ChainedObject<boolean>;
228        isString(): ChainedObject<boolean>;
229        isNumber(): ChainedObject<boolean>;
230        isFinite(): ChainedObject<boolean>;
231        isBoolean(): ChainedObject<boolean>;
232        isDate(): ChainedObject<boolean>;
233        isRegExp(): ChainedObject<boolean>;
234        isNaN(): ChainedObject<boolean>;
235        isNull(): ChainedObject<boolean>;
236        isUndefined(): ChainedObject<boolean>;
237        value(): T;
238    }
239
240    export interface ChainedArray<T> extends ChainedObject<Array<T>> {
241        each(iterator: Iterator_<T, void>, context?: any): ChainedObject<void>;
242        forEach(iterator: Iterator_<T, void>, context?: any): ChainedObject<void>;
243        map<U>(iterator: Iterator_<T, U>, context?: any): ChainedArray<U>;
244        collect<U>(iterator: Iterator_<T, U>, context?: any): ChainedArray<U>;
245        reduce(iterator: Reducer<T, T>, initialValue?: T, context?: any): ChainedObject<T>;
246        reduce<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): ChainedObject<U>;
247        foldl(iterator: Reducer<T, T>, initialValue?: T, context?: any): ChainedObject<T>;
248        foldl<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): ChainedObject<U>;
249        inject(iterator: Reducer<T, T>, initialValue?: T, context?: any): ChainedObject<T>;
250        inject<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): ChainedObject<U>;
251        reduceRight(iterator: Reducer<T, T>, initialValue?: T, context?: any): ChainedObject<T>;
252        reduceRight<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): ChainedObject<U>;
253        foldr(iterator: Reducer<T, T>, initialValue?: T, context?: any): ChainedObject<T>;
254        foldr<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): ChainedObject<U>;
255        find(iterator: Iterator_<T, boolean>, context?: any): ChainedObject<T>;
256        detect(iterator: Iterator_<T, boolean>, context?: any): ChainedObject<T>;
257        filter(iterator: Iterator_<T, boolean>, context?: any): ChainedArray<T>;
258        select(iterator: Iterator_<T, boolean>, context?: any): ChainedArray<T>;
259        where(properties: Object): ChainedArray<T>;
260        findWhere(properties: Object): ChainedObject<T>;
261        reject(iterator: Iterator_<T, boolean>, context?: any): ChainedArray<T>;
262        every(iterator?: Iterator_<T, boolean>, context?: any): ChainedObject<boolean>;
263        all(iterator?: Iterator_<T, boolean>, context?: any): ChainedObject<boolean>;
264        some(iterator?: Iterator_<T, boolean>, context?: any): ChainedObject<boolean>;
265        any(iterator?: Iterator_<T, boolean>, context?: any): ChainedObject<boolean>;
266        contains(value: T): ChainedObject<boolean>;
267        include(value: T): ChainedObject<boolean>;
268        invoke(methodName: string, ...args: any[]): ChainedArray<any>;
269        pluck(propertyName: string): ChainedArray<any>;
270        max(iterator?: Iterator_<T, any>, context?: any): ChainedObject<T>;
271        min(iterator?: Iterator_<T, any>, context?: any): ChainedObject<T>;
272        sortBy(iterator: Iterator_<T, any>, context?: any): ChainedArray<T>;
273        sortBy(propertyName: string): ChainedArray<T>;
274        // Should return ChainedDictionary<T[]>, but expansive recursion not allowed
275        groupBy(iterator?: Iterator_<T, any>, context?: any): ChainedDictionary<any[]>;
276        groupBy(propertyName: string): ChainedDictionary<any[]>;
277        countBy(iterator?: Iterator_<T, any>, context?: any): ChainedDictionary<number>;
278        countBy(propertyName: string): ChainedDictionary<number>;
279        shuffle(): ChainedArray<T>;
280        toArray(): ChainedArray<T>;
281        size(): ChainedObject<number>;
282        first(): ChainedObject<T>;
283        first(count: number): ChainedArray<T>;
284        head(): ChainedObject<T>;
285        head(count: number): ChainedArray<T>;
286        take(): ChainedObject<T>;
287        take(count: number): ChainedArray<T>;
288        initial(): ChainedObject<T>;
289        initial(count: number): ChainedArray<T>;
290        last(): ChainedObject<T>;
291        last(count: number): ChainedArray<T>;
292        rest(index?: number): ChainedArray<T>;
293        compact(): ChainedArray<T>;
294        flatten<U>(shallow?: boolean): ChainedArray<U>;
295        without(...values: T[]): ChainedArray<T>;
296        union(...arrays: T[][]): ChainedArray<T>;
297        intersection(...arrays: T[][]): ChainedArray<T>;
298        difference(...others: T[][]): ChainedArray<T>;
299        uniq(isSorted?: boolean): ChainedArray<T>;
300        uniq<U>(isSorted: boolean, iterator: Iterator_<T, U>, context?: any): ChainedArray<U>;
301        unique(isSorted?: boolean): ChainedArray<T>;
302        unique<U>(isSorted: boolean, iterator: Iterator_<T, U>, context?: any): ChainedArray<U>;
303        zip(...arrays: any[][]): ChainedArray<any[]>;
304        object(): ChainedObject<any>;
305        object(values: any[]): ChainedObject<any>;
306        indexOf(value: T, isSorted?: boolean): ChainedObject<number>;
307        lastIndexOf(value: T, fromIndex?: number): ChainedObject<number>;
308        sortedIndex(obj: T, propertyName: string): ChainedObject<number>;
309        sortedIndex(obj: T, iterator?: Iterator_<T, any>, context?: any): ChainedObject<number>;
310        // Methods from Array
311        concat(...items: T[]): ChainedArray<T>;
312        join(separator?: string): ChainedObject<string>;
313        pop(): ChainedObject<T>;
314        push(...items: T[]): ChainedObject<number>;
315        reverse(): ChainedArray<T>;
316        shift(): ChainedObject<T>;
317        slice(start: number, end?: number): ChainedArray<T>;
318        sort(compareFn?: (a: T, b: T) => number): ChainedArray<T>;
319        splice(start: number): ChainedArray<T>;
320        splice(start: number, deleteCount: number, ...items: T[]): ChainedArray<T>;
321        unshift(...items: T[]): ChainedObject<number>;
322        // Methods from ChainedObject with promoted return types
323        extend(...sources: any[]): ChainedArray<T>;
324        pick(...keys: string[]): ChainedArray<T>;
325        omit(...keys: string[]): ChainedArray<T>;
326        defaults(...defaults: any[]): ChainedArray<T>;
327        clone(): ChainedArray<T>;
328        tap(interceptor: (object: T[]) => void): ChainedArray<T>;
329    }
330
331    export interface ChainedDictionary<T> extends ChainedObject<Dictionary<T>> {
332        each(iterator: Iterator_<T, void>, context?: any): ChainedObject<void>;
333        forEach(iterator: Iterator_<T, void>, context?: any): ChainedObject<void>;
334        map<U>(iterator: Iterator_<T, U>, context?: any): ChainedArray<U>;
335        collect<U>(iterator: Iterator_<T, U>, context?: any): ChainedArray<U>;
336        reduce(iterator: Reducer<T, T>, initialValue?: T, context?: any): ChainedObject<T>;
337        reduce<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): ChainedObject<U>;
338        foldl(iterator: Reducer<T, T>, initialValue?: T, context?: any): ChainedObject<T>;
339        foldl<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): ChainedObject<U>;
340        inject(iterator: Reducer<T, T>, initialValue?: T, context?: any): ChainedObject<T>;
341        inject<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): ChainedObject<U>;
342        reduceRight(iterator: Reducer<T, T>, initialValue?: T, context?: any): ChainedObject<T>;
343        reduceRight<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): ChainedObject<U>;
344        foldr(iterator: Reducer<T, T>, initialValue?: T, context?: any): ChainedObject<T>;
345        foldr<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): ChainedObject<U>;
346        find(iterator: Iterator_<T, boolean>, context?: any): ChainedObject<T>;
347        detect(iterator: Iterator_<T, boolean>, context?: any): ChainedObject<T>;
348        filter(iterator: Iterator_<T, boolean>, context?: any): ChainedArray<T>;
349        select(iterator: Iterator_<T, boolean>, context?: any): ChainedArray<T>;
350        where(properties: Object): ChainedArray<T>;
351        findWhere(properties: Object): ChainedObject<T>;
352        reject(iterator: Iterator_<T, boolean>, context?: any): ChainedArray<T>;
353        every(iterator?: Iterator_<T, boolean>, context?: any): ChainedObject<boolean>;
354        all(iterator?: Iterator_<T, boolean>, context?: any): ChainedObject<boolean>;
355        some(iterator?: Iterator_<T, boolean>, context?: any): ChainedObject<boolean>;
356        any(iterator?: Iterator_<T, boolean>, context?: any): ChainedObject<boolean>;
357        contains(value: T): ChainedObject<boolean>;
358        include(value: T): ChainedObject<boolean>;
359        invoke(methodName: string, ...args: any[]): ChainedArray<any>;
360        pluck(propertyName: string): ChainedArray<any>;
361        max(iterator?: Iterator_<T, any>, context?: any): ChainedObject<T>;
362        min(iterator?: Iterator_<T, any>, context?: any): ChainedObject<T>;
363        sortBy(iterator: Iterator_<T, any>, context?: any): ChainedArray<T>;
364        sortBy(propertyName: string): ChainedArray<T>;
365        // Should return ChainedDictionary<T[]>, but expansive recursion not allowed
366        groupBy(iterator?: Iterator_<T, any>, context?: any): ChainedDictionary<any[]>;
367        groupBy(propertyName: string): ChainedDictionary<any[]>;
368        countBy(iterator?: Iterator_<T, any>, context?: any): ChainedDictionary<number>;
369        countBy(propertyName: string): ChainedDictionary<number>;
370        shuffle(): ChainedArray<T>;
371        toArray(): ChainedArray<T>;
372        size(): ChainedObject<number>;
373        // Methods from ChainedObject with promoted return types
374        extend(...sources: any[]): ChainedDictionary<T>;
375        pick(...keys: string[]): ChainedDictionary<T>;
376        omit(...keys: string[]): ChainedDictionary<T>;
377        defaults(...defaults: any[]): ChainedDictionary<T>;
378        clone(): ChainedDictionary<T>;
379        tap(interceptor: (object: Dictionary<T>) => void): ChainedDictionary<T>;
380    }
381
382    export interface TemplateSettings {
383        evaluate?: RegExp;
384        interpolate?: RegExp;
385        escape?: RegExp;
386        variable?: string;
387    }
388
389    export interface Static {
390        <T>(list: T[]): WrappedArray<T>;
391        <T>(list: Dictionary<T>): WrappedDictionary<T>;
392        <T extends Function>(func: T): WrappedFunction<T>;
393        <T>(obj: T): WrappedObject<T>;
394
395        chain<T>(list: T[]): ChainedArray<T>;
396        chain<T>(list: Dictionary<T>): ChainedDictionary<T>;
397        chain<T>(obj: T): ChainedObject<T>;
398
399        each<T>(list: T[], iterator: Iterator_<T, void>, context?: any): void;
400        each<T>(list: Dictionary<T>, iterator: Iterator_<T, void>, context?: any): void;
401        forEach<T>(list: T[], iterator: Iterator_<T, void>, context?: any): void;
402        forEach<T>(list: Dictionary<T>, iterator: Iterator_<T, void>, context?: any): void;
403
404        map<T, U>(list: T[], iterator: Iterator_<T, U>, context?: any): U[];
405        map<T, U>(list: Dictionary<T>, iterator: Iterator_<T, U>, context?: any): U[];
406        collect<T, U>(list: T[], iterator: Iterator_<T, U>, context?: any): U[];
407        collect<T, U>(list: Dictionary<T>, iterator: Iterator_<T, U>, context?: any): U[];
408
409        reduce<T>(list: T[], iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
410        reduce<T, U>(list: T[], iterator: Reducer<T, U>, initialValue: U, context?: any): U;
411        reduce<T>(list: Dictionary<T>, iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
412        reduce<T, U>(list: Dictionary<T>, iterator: Reducer<T, U>, initialValue: U, context?: any): U;
413        foldl<T>(list: T[], iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
414        foldl<T, U>(list: T[], iterator: Reducer<T, U>, initialValue: U, context?: any): U;
415        foldl<T>(list: Dictionary<T>, iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
416        foldl<T, U>(list: Dictionary<T>, iterator: Reducer<T, U>, initialValue: U, context?: any): U;
417        inject<T>(list: T[], iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
418        inject<T, U>(list: T[], iterator: Reducer<T, U>, initialValue: U, context?: any): U;
419        inject<T>(list: Dictionary<T>, iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
420        inject<T, U>(list: Dictionary<T>, iterator: Reducer<T, U>, initialValue: U, context?: any): U;
421
422        reduceRight<T>(list: T[], iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
423        reduceRight<T, U>(list: T[], iterator: Reducer<T, U>, initialValue: U, context?: any): U;
424        reduceRight<T>(list: Dictionary<T>, iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
425        reduceRight<T, U>(list: Dictionary<T>, iterator: Reducer<T, U>, initialValue: U, context?: any): U;
426        foldr<T>(list: T[], iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
427        foldr<T, U>(list: T[], iterator: Reducer<T, U>, initialValue: U, context?: any): U;
428        foldr<T>(list: Dictionary<T>, iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
429        foldr<T, U>(list: Dictionary<T>, iterator: Reducer<T, U>, initialValue: U, context?: any): U;
430
431        find<T>(list: T[], iterator: Iterator_<T, boolean>, context?: any): T;
432        find<T>(list: Dictionary<T>, iterator: Iterator_<T, boolean>, context?: any): T;
433        detect<T>(list: T[], iterator: Iterator_<T, boolean>, context?: any): T;
434        detect<T>(list: Dictionary<T>, iterator: Iterator_<T, boolean>, context?: any): T;
435
436        filter<T>(list: T[], iterator: Iterator_<T, boolean>, context?: any): T[];
437        filter<T>(list: Dictionary<T>, iterator: Iterator_<T, boolean>, context?: any): T[];
438        select<T>(list: T[], iterator: Iterator_<T, boolean>, context?: any): T[];
439        select<T>(list: Dictionary<T>, iterator: Iterator_<T, boolean>, context?: any): T[];
440
441        where<T>(list: T[], properties: Object): T[];
442        where<T>(list: Dictionary<T>, properties: Object): T[];
443
444        findWhere<T>(list: T[], properties: Object): T;
445        findWhere<T>(list: Dictionary<T>, properties: Object): T;
446
447        reject<T>(list: T[], iterator: Iterator_<T, boolean>, context?: any): T[];
448        reject<T>(list: Dictionary<T>, iterator: Iterator_<T, boolean>, context?: any): T[];
449
450        every<T>(list: T[], iterator?: Iterator_<T, boolean>, context?: any): boolean;
451        every<T>(list: Dictionary<T>, iterator?: Iterator_<T, boolean>, context?: any): boolean;
452        all<T>(list: T[], iterator?: Iterator_<T, boolean>, context?: any): boolean;
453        all<T>(list: Dictionary<T>, iterator?: Iterator_<T, boolean>, context?: any): boolean;
454
455        some<T>(list: T[], iterator?: Iterator_<T, boolean>, context?: any): boolean;
456        some<T>(list: Dictionary<T>, iterator?: Iterator_<T, boolean>, context?: any): boolean;
457        any<T>(list: T[], iterator?: Iterator_<T, boolean>, context?: any): boolean;
458        any<T>(list: Dictionary<T>, iterator?: Iterator_<T, boolean>, context?: any): boolean;
459
460        contains<T>(list: T[], value: T): boolean;
461        contains<T>(list: Dictionary<T>, value: T): boolean;
462        include<T>(list: T[], value: T): boolean;
463        include<T>(list: Dictionary<T>, value: T): boolean;
464
465        invoke(list: any[], methodName: string, ...args: any[]): any[];
466        invoke(list: Dictionary<any>, methodName: string, ...args: any[]): any[];
467
468        pluck(list: any[], propertyName: string): any[];
469        pluck(list: Dictionary<any>, propertyName: string): any[];
470
471        max<T>(list: T[], iterator?: Iterator_<T, any>, context?: any): T;
472        max<T>(list: Dictionary<T>, iterator?: Iterator_<T, any>, context?: any): T;
473
474        min<T>(list: T[], iterator?: Iterator_<T, any>, context?: any): T;
475        min<T>(list: Dictionary<T>, iterator?: Iterator_<T, any>, context?: any): T;
476
477        sortBy<T>(list: T[], iterator: Iterator_<T, any>, context?: any): T[];
478        sortBy<T>(list: Dictionary<T>, iterator: Iterator_<T, any>, context?: any): T[];
479        sortBy<T>(list: T[], propertyName: string): T[];
480        sortBy<T>(list: Dictionary<T>, propertyName: string): T[];
481
482        groupBy<T>(list: T[], iterator?: Iterator_<T, any>, context?: any): Dictionary<T[]>;
483        groupBy<T>(list: Dictionary<T>, iterator?: Iterator_<T, any>, context?: any): Dictionary<T[]>;
484        groupBy<T>(list: T[], propertyName: string): Dictionary<T[]>;
485        groupBy<T>(list: Dictionary<T>, propertyName: string): Dictionary<T[]>;
486
487        countBy<T>(list: T[], iterator?: Iterator_<T, any>, context?: any): Dictionary<number>;
488        countBy<T>(list: Dictionary<T>, iterator?: Iterator_<T, any>, context?: any): Dictionary<number>;
489        countBy<T>(list: T[], propertyName: string): Dictionary<number>;
490        countBy<T>(list: Dictionary<T>, propertyName: string): Dictionary<number>;
491
492        shuffle<T>(list: T[]): T[];
493        shuffle<T>(list: Dictionary<T>): T[];
494
495        toArray<T>(list: T[]): T[];
496        toArray<T>(list: Dictionary<T>): T[];
497
498        size<T>(list: T[]): number;
499        size<T>(list: Dictionary<T>): number;
500
501        first<T>(list: T[]): T;
502        first<T>(list: T[], count: number): T[];
503        head<T>(list: T[]): T;
504        head<T>(list: T[], count: number): T[];
505        take<T>(list: T[]): T;
506        take<T>(list: T[], count: number): T[];
507
508        initial<T>(list: T[]): T;
509        initial<T>(list: T[], count: number): T[];
510
511        last<T>(list: T[]): T;
512        last<T>(list: T[], count: number): T[];
513
514        rest<T>(list: T[], index?: number): T[];
515
516        compact<T>(list: T[]): T[];
517
518        flatten<T>(list: T[][]): T[];
519        flatten<T>(array: any[], shallow?: boolean): T[];
520
521        without<T>(list: T[], ...values: T[]): T[];
522
523        union<T>(...arrays: T[][]): T[];
524
525        intersection<T>(...arrays: T[][]): T[];
526
527        difference<T>(list: T[], ...others: T[][]): T[];
528
529        uniq<T>(list: T[], isSorted?: boolean): T[];
530        uniq<T, U>(list: T[], isSorted: boolean, iterator: Iterator_<T, U>, context?: any): U[];
531        unique<T>(list: T[], isSorted?: boolean): T[];
532        unique<T, U>(list: T[], isSorted: boolean, iterator: Iterator_<T, U>, context?: any): U[];
533
534        zip<T0, T1>(a0: T0[], a1: T1[]): Tuple2<T0, T1>[];
535        zip<T0, T1, T2>(a0: T0[], a1: T1[], a2: T2[]): Tuple3<T0, T1, T2>[];
536        zip<T0, T1, T2, T3>(a0: T0[], a1: T1[], a2: T2[], a3: T3[]): Tuple4<T0, T1, T2, T3>[];
537        zip(...arrays: any[][]): any[][];
538
539        object(list: any[][]): any;
540        object(keys: string[], values: any[]): any;
541
542        indexOf<T>(list: T[], value: T, isSorted?: boolean): number;
543
544        lastIndexOf<T>(list: T[], value: T, fromIndex?: number): number;
545
546        sortedIndex<T>(list: T[], obj: T, propertyName: string): number;
547        sortedIndex<T>(list: T[], obj: T, iterator?: Iterator_<T, any>, context?: any): number;
548
549        range(stop: number): number[];
550        range(start: number, stop: number, step?: number): number[];
551
552        bind<T extends Function>(func: T, object: any): T;
553        bind(func: Function, object: any, ...args: any[]): Function;
554
555        bindAll<T>(object: T, ...methodNames: string[]): T;
556
557        partial(func: Function, ...args: any[]): Function;
558
559        memoize<T extends Function>(func: T, hashFunction?: Function): T;
560
561        delay(func: Function, wait: number, ...args: any[]): number;
562
563        defer(func: Function, ...args: any[]): number;
564
565        throttle<T extends Function>(func: T, wait: number): T;
566
567        debounce<T extends Function>(func: T, wait: number, immediate?: boolean): T;
568
569        once<T extends Function>(func: T): T;
570
571        after<T extends Function>(count: number, func: T): T;
572
573        wrap<T extends Function>(func: T, wrapper: (func: T, ...args: any[]) => any): T;
574
575        compose(...funcs: Function[]): Function;
576
577        keys(object: any): string[];
578
579        values(object: any): any[];
580
581        pairs(object: any): any[][];
582
583        invert(object: any): any;
584
585        functions(object: any): string[];
586        methods(object: any): string[];
587
588        extend<T>(destination: T, ...sources: any[]): T;
589
590        pick<T>(object: T, ...keys: string[]): T;
591
592        omit<T>(object: T, ...keys: string[]): T;
593
594        defaults<T>(object: T, ...defaults: any[]): T;
595
596        clone<T>(object: T): T;
597
598        tap<T>(object: T, interceptor: (object: T) => void): T;
599
600        has(object: any, key: string): boolean;
601
602        isEqual<T>(object: T, other: T): boolean;
603
604        isEmpty(object: any): boolean;
605        isElement(object: any): boolean;
606        isArray(object: any): boolean;
607        isObject(value: any): boolean;
608        isArguments(object: any): boolean;
609        isFunction(object: any): boolean;
610        isString(object: any): boolean;
611        isNumber(object: any): boolean;
612        isFinite(object: any): boolean;
613        isBoolean(object: any): boolean;
614        isDate(object: any): boolean;
615        isRegExp(object: any): boolean;
616        isNaN(object: any): boolean;
617        isNull(object: any): boolean;
618        isUndefined(value: any): boolean;
619
620        noConflict(): Static;
621
622        identity<T>(value: T): T;
623
624        times<U>(n: number, iterator: Iterator_<number, U>, context?: any): U[];
625
626        random(max: number): number;
627        random(min: number, max: number): number;
628
629        mixin(object: any): void;
630
631        uniqueId(): number;
632        uniqueId(prefix: string): string;
633
634        escape(s: string): string;
635
636        unescape(s: string): string;
637
638        result(object: any, property: string): any;
639
640        templateSettings: TemplateSettings;
641
642        template(templateString: string): (data: any) => string;
643        template(templateString: string, data: any, settings?: TemplateSettings): string;
644    }
645}
646
647declare var _: Underscore.Static;
648
649// @Filename: underscoreTest1_underscoreTests.ts
650/// <reference path="underscoreTest1_underscore.ts" />
651
652declare var $;
653declare function alert(x: string): void;
654
655_.each([1, 2, 3], (num) => alert(num.toString()));
656_.each({ one: 1, two: 2, three: 3 }, (value: number, key?: string) => alert(value.toString()));
657
658_.map([1, 2, 3], (num) => num * 3);
659_.map({ one: 1, two: 2, three: 3 }, (value: number, key?: string) => value * 3);
660
661var sum = _.reduce([1, 2, 3], (memo, num) => memo + num, 0);
662
663var list = [[0, 1], [2, 3], [4, 5]];
664var flat = _.reduceRight(list, (a, b) => a.concat(b), []);
665
666var even = _.find([1, 2, 3, 4, 5, 6], (num) => num % 2 == 0);
667
668var evens = _.filter([1, 2, 3, 4, 5, 6], (num) => num % 2 == 0);
669
670var listOfPlays = [{ title: "Cymbeline", author: "Shakespeare", year: 1611 }, { title: "The Tempest", author: "Shakespeare", year: 1611 }, { title: "Other", author: "Not Shakespeare", year: 2012 }];
671_.where(listOfPlays, { author: "Shakespeare", year: 1611 });
672
673var odds = _.reject([1, 2, 3, 4, 5, 6], (num) => num % 2 == 0);
674
675_.all([true, 1, null, 'yes'], _.identity);
676
677_.any([null, 0, 'yes', false]);
678
679_.contains([1, 2, 3], 3);
680
681_.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
682
683var stooges = [{ name: 'moe', age: 40 }, { name: 'larry', age: 50 }, { name: 'curly', age: 60 }];
684_.pluck(stooges, 'name');
685
686_.max(stooges, (stooge) => stooge.age);
687
688var numbers = [10, 5, 100, 2, 1000];
689_.min(numbers);
690
691_.sortBy([1, 2, 3, 4, 5, 6], (num) => Math.sin(num));
692
693
694// not sure how this is typechecking at all.. Math.floor(e) is number not string..?
695_([1.3, 2.1, 2.4]).groupBy((e: number, i?: number, list?: number[]) => Math.floor(e));
696_.groupBy([1.3, 2.1, 2.4], (num: number) => Math.floor(num));
697_.groupBy(['one', 'two', 'three'], 'length');
698
699_.countBy([1, 2, 3, 4, 5], (num) => num % 2 == 0 ? 'even' : 'odd');
700
701_.shuffle([1, 2, 3, 4, 5, 6]);
702
703// (function(){ return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
704
705_.size({ one: 1, two: 2, three: 3 });
706
707///////////////////////////////////////////////////////////////////////////////////////
708
709_.first([5, 4, 3, 2, 1]);
710_.initial([5, 4, 3, 2, 1]);
711_.last([5, 4, 3, 2, 1]);
712_.rest([5, 4, 3, 2, 1]);
713_.compact([0, 1, false, 2, '', 3]);
714
715_.flatten([1, 2, 3, 4]);
716_.flatten([1, [2]]);
717
718// typescript doesn't like the elements being different
719_.flatten([1, [2], [3, [[4]]]]);
720_.flatten([1, [2], [3, [[4]]]], true);
721_.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
722_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
723_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
724_.difference([1, 2, 3, 4, 5], [5, 2, 10]);
725_.uniq([1, 2, 1, 3, 1, 4]);
726_.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]);
727_.object(['moe', 'larry', 'curly'], [30, 40, 50]);
728_.object([['moe', 30], ['larry', 40], ['curly', 50]]);
729_.indexOf([1, 2, 3], 2);
730_.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
731_.sortedIndex([10, 20, 30, 40, 50], 35);
732_.range(10);
733_.range(1, 11);
734_.range(0, 30, 5);
735_.range(0, 30, 5);
736_.range(0);
737
738///////////////////////////////////////////////////////////////////////////////////////
739
740var func = function (greeting) { return greeting + ': ' + this.name };
741// need a second var otherwise typescript thinks func signature is the above func type,
742// instead of the newly returned _bind => func type.
743var func2 = _.bind(func, { name: 'moe' }, 'hi');
744func2();
745
746var buttonView = {
747    label: 'underscore',
748    onClick: function () { alert('clicked: ' + this.label); },
749    onHover: function () { alert('hovering: ' + this.label); }
750};
751_.bindAll(buttonView);
752$('#underscore_button').bind('click', buttonView.onClick);
753
754var fibonacci = _.memoize(function (n) {
755    return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
756});
757
758var log = _.bind((message?: string, ...rest: string[]) => { }, Date);
759_.delay(log, 1000, 'logged later');
760
761_.defer(function () { alert('deferred'); });
762
763var updatePosition = () => alert('updating position...');
764var throttled = _.throttle(updatePosition, 100);
765$(null).scroll(throttled);
766
767var calculateLayout = () => alert('calculating layout...');
768var lazyLayout = _.debounce(calculateLayout, 300);
769$(null).resize(lazyLayout);
770
771var createApplication = () => alert('creating application...');
772var initialize = _.once(createApplication);
773initialize();
774initialize();
775
776var notes: any[];
777var render = () => alert("rendering...");
778var renderNotes = _.after(notes.length, render);
779_.each(notes, (note) => note.asyncSave({ success: renderNotes }));
780
781var hello = function (name) { return "hello: " + name; };
782hello = _.wrap(hello, (func, arg) => { return "before, " + func(arg) + ", after"; });
783hello("moe");
784
785var greet = function (name) { return "hi: " + name; };
786var exclaim = function (statement) { return statement + "!"; };
787var welcome = _.compose(exclaim, greet);
788welcome('moe');
789
790///////////////////////////////////////////////////////////////////////////////////////
791
792_.keys({ one: 1, two: 2, three: 3 });
793_.values({ one: 1, two: 2, three: 3 });
794_.pairs({ one: 1, two: 2, three: 3 });
795_.invert({ Moe: "Moses", Larry: "Louis", Curly: "Jerome" });
796_.functions(_);
797_.extend({ name: 'moe' }, { age: 50 });
798_.pick({ name: 'moe', age: 50, userid: 'moe1' }, 'name', 'age');
799_.omit({ name: 'moe', age: 50, userid: 'moe1' }, 'userid');
800
801var iceCream = { flavor: "chocolate" };
802_.defaults(iceCream, { flavor: "vanilla", sprinkles: "lots" });
803
804_.clone({ name: 'moe' });
805
806_.chain([1, 2, 3, 200])
807    .filter(function (num) { return num % 2 == 0; })
808    .tap(<any>alert)
809    .map(function (num) { return num * num })
810    .value();
811
812_.has({ a: 1, b: 2, c: 3 }, "b");
813
814var moe = { name: 'moe', luckyNumbers: [13, 27, 34] };
815var clone = { name: 'moe', luckyNumbers: [13, 27, 34] };
816moe == clone;
817_.isEqual(moe, clone);
818
819_.isEmpty([1, 2, 3]);
820_.isEmpty({});
821
822_.isElement($('body')[0]);
823
824(function () { return _.isArray(arguments); })();
825_.isArray([1, 2, 3]);
826
827_.isObject({});
828_.isObject(1);
829
830
831// (() => { return _.isArguments(arguments); })(1, 2, 3);
832_.isArguments([1, 2, 3]);
833
834_.isFunction(alert);
835
836_.isString("moe");
837
838_.isNumber(8.4 * 5);
839
840_.isFinite(-101);
841
842_.isFinite(-Infinity);
843
844_.isBoolean(null);
845
846_.isDate(new Date());
847
848_.isRegExp(/moe/);
849
850_.isNaN(NaN);
851isNaN(undefined);
852_.isNaN(undefined);
853
854_.isNull(null);
855_.isNull(undefined);
856
857_.isUndefined((<any>null).missingVariable);
858
859///////////////////////////////////////////////////////////////////////////////////////
860
861var underscore = _.noConflict();
862
863var moe2 = { name: 'moe' };
864moe2 === _.identity(moe);
865
866var genie;
867
868_.times(3, function (n) { genie.grantWishNumber(n); });
869
870_.random(0, 100);
871
872_.mixin({
873    capitalize: function (string) {
874        return string.charAt(0).toUpperCase() + string.substring(1).toLowerCase();
875    }
876});
877(<any>_("fabio")).capitalize();
878
879_.uniqueId('contact_');
880
881_.escape('Curly, Larry & Moe');
882
883var object = { cheese: 'crumpets', stuff: function () { return 'nonsense'; } };
884_.result(object, 'cheese');
885
886_.result(object, 'stuff');
887
888var compiled = _.template("hello: <%= name %>");
889compiled({ name: 'moe' });
890var list2 = "<% _.each(people, function(name) { %> <li><%= name %></li> <% }); %>";
891_.template(list2, { people: ['moe', 'curly', 'larry'] });
892var template = _.template("<b><%- value %></b>");
893template({ value: '<script>' });
894var compiled2 = _.template("<% print('Hello ' + epithet); %>");
895compiled2({ epithet: "stooge" });
896_.templateSettings = {
897    interpolate: /\{\{(.+?)\}\}/g
898};
899var template2 = _.template("Hello {{ name }}!");
900template2({ name: "Mustache" });
901_.template("Using 'with': <%= data.answer %>", { answer: 'no' }, { variable: 'data' });