From 498740aa76af7bf0e6de2dfb949610c9a6ca9ee7 Mon Sep 17 00:00:00 2001 From: Boris Yankov Date: Fri, 5 Oct 2012 19:51:30 +0300 Subject: [PATCH] Underscore definitions added --- Definitions/underscore.d.ts | 158 +++++++++++++++++++++++ Tests/underscore.ts | 249 ++++++++++++++++++++++++++++++++++++ 2 files changed, 407 insertions(+) create mode 100644 Definitions/underscore.d.ts create mode 100644 Tests/underscore.ts diff --git a/Definitions/underscore.d.ts b/Definitions/underscore.d.ts new file mode 100644 index 000000000..6f5779f46 --- /dev/null +++ b/Definitions/underscore.d.ts @@ -0,0 +1,158 @@ +// Type definitions for Underscore 1.4.1 +// https://github.com/borisyankov/DefinitelyTyped + +interface KeyValuePair { + key: string; + value: any; +} + +interface TemplateSettings { + evaluate?: RegExp; + interpolate?: RegExp; + escape?: RegExp; +} + +interface UnderscoreStatic { + + /**** + Collections + *****/ + each(list: any[], iterator: any, context?: any): any[]; // interface Iterator = (element, index, list) => any; + each(obj: any, iterator: any, context?: any): any[]; // (value, key, list) + forEach(list: any[], iterator: any, context?: any): any[]; + forEach(obj: any, iterator: any, context?: any): any[]; + + map(list: any[], iterator: any, context?: any): any[]; + map(obj: any, iterator: any, context?: any): any[]; + collect(list: any[], iterator: any, context?: any): any[]; + collect(obj: any, iterator: any, context?: any): any[]; + + reduce(list: any[], iterator: any, memo: any, context?: any): any[]; + inject(list: any[], iterator: any, memo: any, context?: any): any[]; + foldl(list: any[], iterator: any, memo: any, context?: any): any[]; + + reduceRight(list: any[], iterator: any, memo: any, context?: any): any[]; + foldr(list: any[], iterator: any, memo: any, context?: any): any[]; + find(list: any[], iterator: any, context?: any): any; + detect(list: any[], iterator: any, context?: any): any; + filter(list: any[], iterator: any, context?: any): any[]; + select(list: any[], iterator: any, context?: any): any[]; + where(list: any[], properties: any): any[]; + reject(list: any[], iterator: any, context?: any): any[]; + all(list: any[], iterator: any, context?: any): bool; + _any(list: any[], iterator?: any, context?: any): bool; + contains(list: any, value: any): bool; + contains(list: any[], value: any): bool; + + invoke(list: any[], methodName: string, arguments: any[]): any; + invoke(obj: any, methodName: string, ...arguments: any[]): any; + + pluck(list: any[], propertyName: string): string[]; + max(list: any[], iterator?: any, context?: any): any; + min(list: any[], iterator?: any, context?: any): any; + sortBy(list: any[], iterator?: any, context?: any): any; + groupBy(list: any[], iterator: any): any; + countBy(list: any[], iterator: any): any; + shuffle(list: any[]): any[]; + toArray(list: any): any[]; + size(list: any): number; + + /**** + Arrays + *****/ + first(array: any[], n?: number): any; + head(array: any[], n?: number): any; + take(array: any[], n?: number): any; + initial(array: any[], n?: number): any[]; + last(array: any[], n?: number): any; + rest(array: any[], n?: number): any[]; + tail(array: any[], n?: number): any[]; + drop(array: any[], n?: number): any[]; + compact(array: any[]): any[]; + flatten(array: any[], shallow?: bool): any[]; + without(array: any[], ...values: any[]): any[]; + union(...arrays: any[]): any[]; + intersection(...arrays: any[]): any[]; + difference(array: any[], ...others: any[]): any[]; + uniq(array: any[], isSorted?: bool, iterator?: any): any[]; + zip(...arrays: any[]): any[]; + object(list: any[], values: any[]): any; + indexOf(array: any[], value: any, isSorted?: bool): number; + lastIndexOf(array: any[], value: any, fromIndex?: number): number; + sortedIndex(list: any[], valueL: any, iterator?: any): number; + range(stop: number): any[]; + range(start: number, stop: number, step?: number): any[]; + + /**** + Functions + *****/ + bind(func: any, context: any, ...arguments: any[]): () => any; + bindAll(obj: any, ...methodNames: string[]): any; + memoize(func: any, hashFunction?: any): any; + defer(func: () => any); + delay(func: any, wait: number, ...arguments: any[]): any; + delay(func: any, ...arguments: any[]): any; + throttle(func: any, wait: number): any; + debounce(func: any, wait: number, immediate?: bool): any; + once(func: any): any; + after(count: number, func: any): any; + wrap(func: any, wrapper: any): () => any; + compose(...functions: any[]): any; + + /**** + Objects + *****/ + keys(object: any): any[]; + values(object: any): any[]; + pairs(object: any): KeyValuePair[]; + invert(object: any): any[]; + functions(object: any): string[]; + methods(object: any): string[]; + extend(destination: any, sources: any): any; + pick(object: any, ...keys: string[]): any; + omit(object: any, key: string): any; + omit(object: any, keys: string[]): any; + defaults(object: any, defaults: any): any; + clone(object: any): any; + tap(object: any, interceptor: any): any; + has(object: any, key: string): bool; + isEqual(object: any, other: any): bool; + isEmpty(object: any): bool; + isElement(object: any): bool; + isArray(object: any): bool; + isObject(value: any): bool; + isArguments(object: any): bool; + isFunction(object: any): bool; + isString(object: any): bool; + isNumber(object: any): bool; + isFinite(object: any): bool; + isBoolean(object: any): bool; + isDate(object: any): bool; + isRegExp(object: any): bool; + isNaN(object: any): bool; + isNull(object: any): bool; + isUndefined(value: any): bool; + + /**** + Utility + *****/ + noConflict(): UnderscoreStatic; + identity(value: any): any; + times(n: number, iterator: any, context?: any): any[]; + random(min: number, max: number): number; + mixin(object: any): any; + uniqueId(prefix: string): string; + uniqueId(): number; + escape(string: string): string; + result(object: any, property: any): any; + templateSettings: TemplateSettings; + template(templateString: string, data?: any, settings?: any): (data: any) => string; + + /**** + Chaining + *****/ + chain(obj: any): any; + // (obj).value() +} + +declare var _: UnderscoreStatic; \ No newline at end of file diff --git a/Tests/underscore.ts b/Tests/underscore.ts new file mode 100644 index 000000000..895307b98 --- /dev/null +++ b/Tests/underscore.ts @@ -0,0 +1,249 @@ +/// + +declare var $: any; + +function alert(thing: any) { + $('#content').append('
' + thing + '
'); +} + +$(() => { + + _.each([1, 2, 3], (num) => alert(num)); + _.each({ one: 1, two: 2, three: 3 }, (num, key) => alert(num)); + + _.map([1, 2, 3], (num) => num * 3); + _.map({ one: 1, two: 2, three: 3 }, (num, key) => num * 3); + + var sum = _.reduce([1, 2, 3], (memo, num) => memo + num, 0); + // alert(sum); + + var list = [[0, 1], [2, 3], [4, 5]]; + var flat = _.reduceRight(list, (a, b) => a.concat(b), []); + // alert(flat); + + var even = _.find([1, 2, 3, 4, 5, 6], (num) => num % 2 == 0); + + var evens = _.filter([1, 2, 3, 4, 5, 6], (num) => num % 2 == 0); + + var listOfPlays = [{ title: "Cymbeline", author: "Shakespeare", year: 1611 }, { title: "The Tempest", author: "Shakespeare", year: 1611 }, { title: "Other", author: "Not Shakespeare", year: 2012 }]; + _.where(listOfPlays, { author: "Shakespeare", year: 1611 }); + + var odds = _.reject([1, 2, 3, 4, 5, 6], (num) => num % 2 == 0); + + _.all([true, 1, null, 'yes'], _.identity); + + _._any([null, 0, 'yes', false]); + + _.contains([1, 2, 3], 3); + + _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + + var stooges = [{ name: 'moe', age: 40 }, { name: 'larry', age: 50 }, { name: 'curly', age: 60 }]; + _.pluck(stooges, 'name'); + + var stooges = [{ name: 'moe', age: 40 }, { name: 'larry', age: 50 }, { name: 'curly', age: 60 }]; + _.max(stooges, (stooge) => stooge.age); + + var numbers = [10, 5, 100, 2, 1000]; + _.min(numbers); + + _.sortBy([1, 2, 3, 4, 5, 6], (num) => Math.sin(num)); + + _.groupBy([1.3, 2.1, 2.4], (num) => Math.floor(num)); + _.groupBy(['one', 'two', 'three'], 'length'); + + _.countBy([1, 2, 3, 4, 5], (num) => num % 2 == 0 ? 'even' : 'odd'); + + _.shuffle([1, 2, 3, 4, 5, 6]); + + //(function(){ return _.toArray(arguments).slice(1); })(1, 2, 3, 4); + + _.size({ one: 1, two: 2, three: 3 }); + + /////////////////////////////////////////////////////////////////////////////////////// + + _.first([5, 4, 3, 2, 1]); + _.initial([5, 4, 3, 2, 1]); + _.last([5, 4, 3, 2, 1]); + _.rest([5, 4, 3, 2, 1]); + _.compact([0, 1, false, 2, '', 3]); + //_.flatten([1, [2], [3, [[4]]]]); + //_.flatten([1, [2], [3, [[4]]]], true); + _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); + _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]); + _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]); + _.difference([1, 2, 3, 4, 5], [5, 2, 10]); + _.uniq([1, 2, 1, 3, 1, 4]); + _.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]); + _.object(['moe', 'larry', 'curly'], [30, 40, 50]); + // _.object([['moe', 30], ['larry', 40], ['curly', 50]]); + _.indexOf([1, 2, 3], 2); + _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); + _.sortedIndex([10, 20, 30, 40, 50], 35); + _.range(10); + _.range(1, 11); + _.range(0, 30, 5); + _.range(0, 30, 5); + _.range(0); + + /////////////////////////////////////////////////////////////////////////////////////// + + var func = function (greeting) { return greeting + ': ' + this.name }; + func = _.bind(func, { name: 'moe' }, 'hi'); + // func(); + + var buttonView = { + label: 'underscore', + onClick: function () { alert('clicked: ' + this.label); }, + onHover: function () { console.log('hovering: ' + this.label); } + }; + _.bindAll(buttonView); + //$('#underscore_button').bind('click', buttonView.onClick); + + var fibonacci = _.memoize(function (n) { + return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); + }); + + var log = _.bind(console.log, console); + _.delay(log, 1000, 'logged later'); + + _.defer(function () { alert('deferred'); }); + + var updatePosition = () => alert('updating position...'); + var throttled = _.throttle(updatePosition, 100); + $(window).scroll(throttled); + + var calculateLayout = () => alert('calculating layout...'); + var lazyLayout = _.debounce(calculateLayout, 300); + $(window).resize(lazyLayout); + + var createApplication = () => alert('creating application...'); + var initialize = _.once(createApplication); + initialize(); + initialize(); + + var notes: any[]; + var render = () => alert("rendering..."); + var renderNotes = _.after(notes.length, render); + _.each(notes, (note) => note.asyncSave({ success: renderNotes })); + + var hello = function (name) { return "hello: " + name; }; + hello = _.wrap(hello, (func) => { return "before, " + func("moe") + ", after"; }); + // hello(); + + var greet = function (name) { return "hi: " + name; }; + var exclaim = function (statement) { return statement + "!"; }; + var welcome = _.compose(exclaim, greet); + welcome('moe'); + + /////////////////////////////////////////////////////////////////////////////////////// + + _.keys({ one: 1, two: 2, three: 3 }); + _.values({ one: 1, two: 2, three: 3 }); + _.pairs({ one: 1, two: 2, three: 3 }); + _.invert({ Moe: "Moses", Larry: "Louis", Curly: "Jerome" }); + _.functions(_); + _.extend({ name: 'moe' }, { age: 50 }); + _.pick({ name: 'moe', age: 50, userid: 'moe1' }, 'name', 'age'); + _.omit({ name: 'moe', age: 50, userid: 'moe1' }, 'userid'); + + var iceCream = { flavor: "chocolate" }; + _.defaults(iceCream, { flavor: "vanilla", sprinkles: "lots" }); + + _.clone({ name: 'moe' }); + + _.chain([1, 2, 3, 200]) + .filter(function (num) { return num % 2 == 0; }) + .tap(alert) + .map(function (num) { return num * num }) + .value(); + + _.has({ a: 1, b: 2, c: 3 }, "b"); + + var moe = { name: 'moe', luckyNumbers: [13, 27, 34] }; + var clone = { name: 'moe', luckyNumbers: [13, 27, 34] }; + moe == clone; + _.isEqual(moe, clone); + + _.isEmpty([1, 2, 3]); + _.isEmpty({}); + + _.isElement($('body')[0]); + + (function () { return _.isArray(arguments); })(); + _.isArray([1, 2, 3]); + + _.isObject({}); + _.isObject(1); + + + // (() => { return _.isArguments(arguments); })(1, 2, 3); + _.isArguments([1, 2, 3]); + + _.isFunction(alert); + + _.isString("moe"); + + _.isNumber(8.4 * 5); + + _.isFinite(-101); + + _.isFinite(-Infinity); + + _.isBoolean(null); + + _.isDate(new Date()); + + _.isRegExp(/moe/); + + _.isNaN(NaN); + isNaN(undefined); + _.isNaN(undefined); + + _.isNull(null); + _.isNull(undefined); + + // _.isUndefined(window.missingVariable); + + /////////////////////////////////////////////////////////////////////////////////////// + + var underscore = _.noConflict(); + + var moe2 = { name: 'moe' }; + moe2 === _.identity(moe); + + // _(3).times(function(n){ genie.grantWishNumber(n); }); + + _.random(0, 100); + + _.mixin({ + capitalize: function (string) { + return string.charAt(0).toUpperCase() + string.substring(1).toLowerCase(); + } + }); + // _("fabio").capitalize(); + + _.uniqueId('contact_'); + + _.escape('Curly, Larry & Moe'); + + var object = { cheese: 'crumpets', stuff: function () { return 'nonsense'; } }; + _.result(object, 'cheese'); + + _.result(object, 'stuff'); + + var compiled = _.template("hello: <%= name %>"); + compiled({ name: 'moe' }); + var list2 = "<% _.each(people, function(name) { %>
  • <%= name %>
  • <% }); %>"; + _.template(list2, { people: ['moe', 'curly', 'larry'] }); + var template = _.template("<%- value %>"); + template({ value: '