From c13f86684a7f7684efc451e911b3cb488d2eadbd Mon Sep 17 00:00:00 2001 From: "Omid K. Rad" Date: Thu, 10 Apr 2014 13:28:10 -0700 Subject: [PATCH] Use power of Generics to infer types --- underscore/underscore-tests.ts | 59 ++++++++++++++++----------------- underscore/underscore.d.ts | 60 ++++++++++++++++++++++------------ 2 files changed, 68 insertions(+), 51 deletions(-) diff --git a/underscore/underscore-tests.ts b/underscore/underscore-tests.ts index 64c45a478b..8e0162b58c 100644 --- a/underscore/underscore-tests.ts +++ b/underscore/underscore-tests.ts @@ -3,10 +3,10 @@ declare var $; _.each([1, 2, 3], (num) => alert(num.toString())); -_.each({ one: 1, two: 2, three: 3 }, (value) => alert(value.toString())); +_.each({ one: 1, two: 2, three: 3 }, (value, key) => alert(value.toString())); _.map([1, 2, 3], (num) => num * 3); -_.map({ one: 1, two: 2, three: 3 }, (value: number, key?: string) => value * 3); +_.map({ one: 1, two: 2, three: 3 }, (value, key) => value * 3); //var sum = _.reduce([1, 2, 3], (memo, num) => memo + num, 0); // https://typescript.codeplex.com/workitem/1960 var sum = _.reduce([1, 2, 3], (memo, num) => memo + num, 0); @@ -16,18 +16,20 @@ var list = [[0, 1], [2, 3], [4, 5]]; //var flat = _.reduceRight(list, (a, b) => a.concat(b), []); // https://typescript.codeplex.com/workitem/1960 var flat = _.reduceRight(list, (a, b) => a.concat(b), []); -var even = _.find([1, 2, 3, 4, 5, 6], (num) => num % 2 == 0); +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 firstCapitalLetter = _.find({ a: 'a', b: 'B', c: 'C', d: 'd' }, l => l === l.toUpperCase()); + +var evens = _.filter([1, 2, 3, 4, 5, 6], (num) => num % 2 == 0); + +var capitalLetters = _.filter({ a: 'a', b: 'B', c: 'C', d: 'd' }, l => l === l.toUpperCase()); 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); +var odds = _.reject([1, 2, 3, 4, 5, 6], (num) => num % 2 == 0); -//_.every([true, 1, null, 'yes'], _.identity); // https://typescript.codeplex.com/workitem/1960 -_.every([true, 1, null, 'yes'], _.identity); -_.every<{}>([true, 1, null, 'yes']); +_.every([true, 1, null, 'yes'], _.identity); _.any([null, 0, 'yes', false]); @@ -49,7 +51,7 @@ _.sortBy([1, 2, 3, 4, 5, 6], (num) => Math.sin(num)); _([1.3, 2.1, 2.4]).groupBy((e) => Math.floor(e)); -_.groupBy([1.3, 2.1, 2.4], (num: number) => Math.floor(num).toString()); +_.groupBy([1.3, 2.1, 2.4], (num) => Math.floor(num).toString()); _.groupBy(['one', 'two', 'three'], 'length'); _.indexBy(stooges, 'age')['40'].age; @@ -59,7 +61,7 @@ _(stooges) .indexBy('age') .value()['40'].age; -_.countBy([1, 2, 3, 4, 5], (num) => (num % 2 == 0) ? 'even' : 'odd'); +_.countBy([1, 2, 3, 4, 5], (num) => (num % 2 == 0) ? 'even' : 'odd'); _.shuffle([1, 2, 3, 4, 5, 6]); @@ -87,19 +89,19 @@ _.rest([5, 4, 3, 2, 1]); _.compact([0, 1, false, 2, '', 3]); _.flatten([1, 2, 3, 4]); -_.flatten([1, [2]]); +_.flatten([1, [2]]); // typescript doesn't like the elements being different -_.flatten([1, [2], [3, [[4]]]]); -_.flatten([1, [2], [3, [[4]]]], true); +_.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]); -var r = _.object<{ [key: string]: number }>(['moe', 'larry', 'curly'], [30, 40, 50]); -_.object([['moe', 30], ['larry', 40], ['curly', 50]]); +var r = _.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); @@ -183,18 +185,15 @@ _.clone(['i', 'am', 'an', 'object!']); _([1, 2, 3, 4]) .chain() - .filter((num: number) => { - return num % 2 == 0; - }).tap(alert) - .map((num: number) => { - return num * num; - }) + .filter((num) => { return num % 2 == 0; }) + .tap(alert) + .map((num) => { return num * num; }) .value(); _.chain([1, 2, 3, 200]) - .filter(function (num: number) { return num % 2 == 0; }) + .filter((num) => { return num % 2 == 0; }) .tap(alert) - .map(function (num: number) { return num * num }) + .map((num) => { return num * num; }) .value(); _.has({ a: 1, b: 2, c: 3 }, "b"); @@ -259,7 +258,7 @@ var moe2 = { name: 'moe' }; moe2 === _.identity(moe); var genie; -var r2 = _.times(3, (n) => { return n * n }); +var r2 = _.times(3, (n) => { return n * n }); _(3).times(function (n) { genie.grantWishNumber(n); }); _.random(0, 100); @@ -301,29 +300,27 @@ _(['test', 'test']).pick(['test2', 'test2']); //////////////// Chain Tests function chain_tests() { // https://typescript.codeplex.com/workitem/1960 - var numArray: number[] = _.chain([1, 2, 3, 4, 5, 6, 7, 8]) + var numArray = _.chain([1, 2, 3, 4, 5, 6, 7, 8]) .filter(num => num % 2 == 0) .map(num => num * num) .value(); - var strArray: string[] = _([1, 2, 3, 4]) + var strArray = _([1, 2, 3, 4]) .chain() .filter(num => num % 2 == 0) .tap(alert) .map(num => "string" + num) .value(); - var n : number = _.chain([1, 2, 3, 200]) + var n = _.chain([1, 2, 3, 200]) .filter(num => num % 2 == 0) .tap(alert) .map(num => num * num) .max() .value(); - //If using alternate definition of map (~ line 2200), .value returns any - // because.map matches _Chain as opposed to _ChainOfArrays , which breaks typing on flatten - var hoverOverValueShouldBeNumberNotAny : number = _([1, 2, 3]).chain() - .map(num=> [num, num + 1]) + var hoverOverValueShouldBeNumberNotAny = _([1, 2, 3]).chain() + .map(num => [num, num + 1]) .flatten() .find(num => num % 2 == 0) .value(); diff --git a/underscore/underscore.d.ts b/underscore/underscore.d.ts index 7e4bd99e1e..cc9a3e6e9d 100644 --- a/underscore/underscore.d.ts +++ b/underscore/underscore.d.ts @@ -23,7 +23,7 @@ declare module _ { /** * underscore.js template settings, set templateSettings or pass as an argument - * to 'template()' to overide defaults. + * to 'template()' to override defaults. **/ interface TemplateSettings { /** @@ -200,7 +200,7 @@ interface UnderscoreStatic { /** * The right-associative version of reduce. Delegates to the JavaScript 1.8 version of - * reduceRight, if it exists. Foldr is not as useful in JavaScript as it would be in a + * reduceRight, if it exists. `foldr` is not as useful in JavaScript as it would be in a * language with lazy evaluation. * @param list Reduces the elements of this array. * @param iterator Reduce iterator function for each element in `list`. @@ -233,7 +233,15 @@ interface UnderscoreStatic { * @return The first acceptable found element in `list`, if nothing is found undefined/null is returned. **/ find( - list: _.Collection, + list: _.List, + iterator: _.ListIterator, + context?: any): T; + + /** + * @see _.find + **/ + find( + list: _.Dictionary, iterator: _.ListIterator, context?: any): T; @@ -254,7 +262,15 @@ interface UnderscoreStatic { * @return The filtered list of elements. **/ filter( - list: _.Collection, + list: _.List, + iterator: _.ListIterator, + context?: any): T[]; + + /** + * @see _.filter + **/ + filter( + list: _.Dictionary, iterator: _.ListIterator, context?: any): T[]; @@ -297,7 +313,15 @@ interface UnderscoreStatic { * @return The rejected list of elements. **/ reject( - list: _.Collection, + list: _.List, + iterator: _.ListIterator, + context?: any): T[]; + + /** + * @see _.reject + **/ + reject( + list: _.Dictionary, iterator: _.ListIterator, context?: any): T[]; @@ -497,7 +521,7 @@ interface UnderscoreStatic { * @return An object with the group names as properties where each property contains the number of elements in that group. **/ countBy( - list: _.Collection, + list: _.List, iterator?: _.ListIterator, context?: any): _.Dictionary; @@ -506,7 +530,7 @@ interface UnderscoreStatic { * @param iterator Function name **/ countBy( - list: _.Collection, + list: _.Dictionary, iterator: string, context?: any): _.Dictionary; @@ -603,7 +627,7 @@ interface UnderscoreStatic { /** * Returns everything but the last entry of the array. Especially useful on the arguments object. * Pass n to exclude the last n elements from the result. - * @param array Retreive all elements except the last `n`. + * @param array Retrieve all elements except the last `n`. * @param n Leaves this many elements behind, optional. * @return Returns everything but the last `n` elements of `array`. **/ @@ -711,7 +735,7 @@ interface UnderscoreStatic { * advance that the array is sorted, passing true for isSorted will run a much faster algorithm. If * you want to compute unique items based on a transformation, pass an iterator function. * @param array Array to remove duplicates from. - * @param isSorted True if `array` is already sorted, optiona, default = false. + * @param isSorted True if `array` is already sorted, optional, default = false. * @param iterator Transform the elements of `array` before comparisons for uniqueness. * @param context 'this' object in `iterator`, optional. * @return Copy of `array` where all elements are unique. @@ -817,7 +841,7 @@ interface UnderscoreStatic { * @param array The array to search for the last index of `value`. * @param value The value to search for within `array`. * @param from The starting index for the search, optional. - * @return The index of the last occurance of `value` within `array`. + * @return The index of the last occurrence of `value` within `array`. **/ lastIndexOf( array: _.List, @@ -918,7 +942,7 @@ interface UnderscoreStatic { /** * Much like setTimeout, invokes function after wait milliseconds. If you pass the optional arguments, * they will be forwarded on to the function when it is invoked. - * @param fn Function to delay `waitMS` amount of ms. + * @param func Function to delay `waitMS` amount of ms. * @param wait The amount of milliseconds to delay `fn`. * @arguments Additional arguments to pass to `fn`. **/ @@ -954,7 +978,7 @@ interface UnderscoreStatic { * if you call it again any number of times during the wait period, as soon as that period is over. * If you'd like to disable the leading-edge call, pass {leading: false}, and if you'd like to disable * the execution on the trailing-edge, pass {trailing: false}. - * @param fn Function to throttle `waitMS` ms. + * @param func Function to throttle `waitMS` ms. * @param wait The number of milliseconds to wait before `fn` can be invoked again. * @param options Allows for disabling execution of the throttled function on either the leading or trailing edge. * @return `fn` with a throttle of `wait`. @@ -1030,14 +1054,14 @@ interface UnderscoreStatic { /** * Retrieve all the names of the object's properties. - * @param object Retreive the key or property names from this object. + * @param object Retrieve the key or property names from this object. * @return List of all the property names on `object`. **/ keys(object: any): string[]; /** * Return all of the values of the object's properties. - * @param object Retreive the values of all the properties on this object. + * @param object Retrieve the values of all the properties on this object. * @return List of all the values on `object`. **/ values(object: any): any[]; @@ -2233,9 +2257,7 @@ interface _Chain { * Wrapped type `any[]`. * @see _.map **/ - map(iterator: (value: T, index: number, list: T[]) => TArray[], context?: any): _ChainOfArrays; - //Not sure why this won't work, might be a TypeScript error? - //map(iterator: _.ListIterator, context?: any): _ChainOfArrays; + map(iterator: _.ListIterator, context?: any): _ChainOfArrays; /** * Wrapped type `any[]`. @@ -2247,9 +2269,7 @@ interface _Chain { * Wrapped type `any[]`. * @see _.map **/ - map(iterator: (element: T, key: string, list: any) => TArray[], context?: any): _ChainOfArrays; - //Not sure why this won't work, might be a TypeScript error? - //map(iterator: _.ObjectIterator, context?: any): _ChainOfArrays; + map(iterator: _.ObjectIterator, context?: any): _ChainOfArrays; /** * Wrapped type `any[]`.