Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 85 additions & 73 deletions types/underscore/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -364,25 +364,30 @@ declare module _ {
select: UnderscoreStatic['filter'];

/**
* Looks through each value in the list, returning an array of all the values that contain all
* of the key-value pairs listed in properties.
* @param list List to match elements again `properties`.
* @param properties The properties to check for on each element within `list`.
* @return The elements within `list` that contain the required `properties`.
**/
where<T, U extends {}>(
list: _.List<T>,
properties: U): T[];
* Looks through each value in the collection, returning an array of all the values that matches the
* key-value pairs listed in `properties`.
* @param collection The collection in which to find elements that match `properties`.
* @param properties The properties to check for on the elements within `collection`.
* @return The elements in `collection` that match `properties`.
**/
where<V extends Collection<any>>(
collection: V,
properties: Partial<TypeOfCollection<V>>
): TypeOfCollection<V>[];

/**
* Looks through the list and returns the first value that matches all of the key-value pairs listed in properties.
* @param list Search through this list's elements for the first object with all `properties`.
* @param properties Properties to look for on the elements within `list`.
* @return The first element in `list` that has all `properties`.
**/
findWhere<T, U extends {}>(
list: _.List<T>,
properties: U): T | undefined;
* Looks through the collection and returns the first value that matches all of the key-value
* pairs listed in `properties`.
* If no match is found, or if list is empty, undefined will be returned.
* @param collection The collection in which to find an element that matches `properties`.
* @param properties The properties to check for on the elements within `collection`.
* @return The first element in `collection` that matches `properties` or undefined if
* no match is found.
**/
findWhere<V extends Collection<any>>(
collection: V,
properties: Partial<TypeOfCollection<V>>
): TypeOfCollection<V> | undefined;

/**
* Returns the values in `collection` without the elements that pass a truth test (iteratee).
Expand Down Expand Up @@ -692,23 +697,21 @@ declare module _ {
context?: any): _.Dictionary<number>;

/**
* Returns a shuffled copy of the list, using a version of the Fisher-Yates shuffle.
* @param list List to shuffle.
* @return Shuffled copy of `list`.
**/
shuffle<T>(list: _.Collection<T>): T[];

/**
* Produce a random sample from the `list`. Pass a number to return `n` random elements from the list. Otherwise a single random item will be returned.
* @param list List to sample.
* @return Random sample of `n` elements in `list`.
**/
sample<T>(list: _.Collection<T>, n: number): T[];
* Returns a shuffled copy of the collection, using a version of the Fisher-Yates shuffle.
* @param collection The collection to shuffle.
* @return A shuffled copy of `collection`.
**/
shuffle<V extends Collection<any>>(collection: V): TypeOfCollection<V>[];

/**
* @see _.sample
**/
sample<T>(list: _.Collection<T>): T;
* Produce a random sample from the collection. Pass a number to return `n` random elements from the collection.
* Otherwise a single random item will be returned.
* @param collection The collection to sample.
* @param n The number of elements to sample from the collection.
* @return A random sample of `n` elements from `collection` or a single element if `n` is not specified.
**/
sample<V extends Collection<any>>(collection: V, n: number): TypeOfCollection<V>[];
sample<V extends Collection<any>>(collection: V): TypeOfCollection<V> | undefined;

/**
* Converts the list (anything that can be iterated over), into a real Array. Useful for transmuting
Expand Down Expand Up @@ -4206,16 +4209,22 @@ declare module _ {
select: Underscore<T, V>['filter'];

/**
* Wrapped type `any[]`.
* @see _.where
**/
where<U extends {}>(properties: U): T[];
* Looks through each value in the wrapped collection, returning an array of all the values that matches the
* key-value pairs listed in `properties`.
* @param properties The properties to check for on the elements within the wrapped collection.
* @return The elements in the wrapped collection that match `properties`.
**/
where(properties: Partial<T>): T[];

/**
* Wrapped type `any[]`.
* @see _.findWhere
**/
findWhere<U extends {}>(properties: U): T | undefined;
* Looks through the wrapped collection and returns the first value that matches all of the key-value
* pairs listed in `properties`.
* If no match is found, or if list is empty, undefined will be returned.
* @param properties The properties to check for on the elements within the wrapped collection.
* @return The first element in the wrapped collection that matches `properties` or undefined if
* no match is found.
**/
findWhere(properties: Partial<T>): T | undefined;

/**
* Returns the values in the wrapped collection without the elements that pass a truth test (iteratee).
Expand Down Expand Up @@ -4363,21 +4372,19 @@ declare module _ {
countBy(iterator: string, context?: any): _.Dictionary<number>;

/**
* Wrapped type `any[]`.
* @see _.shuffle
**/
* Returns a shuffled copy of the wrapped collection, using a version of the Fisher-Yates shuffle.
* @return A shuffled copy of the wrapped collection.
**/
shuffle(): T[];

/**
* Wrapped type `any[]`.
* @see _.sample
**/
sample<T>(n: number): T[];

/**
* @see _.sample
**/
sample<T>(): T;
* Produce a random sample from the wrapped collection. Pass a number to return `n` random elements from the
* wrapped collection. Otherwise a single random item will be returned.
* @param n The number of elements to sample from the wrapped collection.
* @return A random sample of `n` elements from the wrapped collection or a single element if `n` is not specified.
**/
sample(n: number): T[];
sample(): T | undefined;

/**
* Wrapped type `any`.
Expand Down Expand Up @@ -5183,16 +5190,22 @@ declare module _ {
select: _Chain<T, V>['filter'];

/**
* Wrapped type `any[]`.
* @see _.where
**/
where<U extends {}>(properties: U): _Chain<T>;
* Looks through each value in the wrapped collection, returning an array of all the values that matches the
* key-value pairs listed in `properties`.
* @param properties The properties to check for on the elements within the wrapped collection.
* @return The elements in the wrapped collection that match `properties` in a chain wrapper.
**/
where(properties: Partial<T>): _Chain<T, T[]>;

/**
* Wrapped type `any[]`.
* @see _.findWhere
**/
findWhere<U extends {}>(properties: U): _ChainSingle<T>;
* Looks through the wrapped collection and returns the first value that matches all of the key-value
* pairs listed in `properties`.
* If no match is found, or if list is empty, undefined will be returned.
* @param properties The properties to check for on the elements within the wrapped collection.
* @return The first element in the wrapped collection that matches `properties` or undefined if
* no match is found. The result will be wrapped in a chain wrapper.
**/
findWhere(properties: Partial<T>): _ChainSingle<T | undefined>;

/**
* Returns the values in the wrapped collection without the elements that pass a truth test (iteratee).
Expand Down Expand Up @@ -5341,21 +5354,20 @@ declare module _ {
countBy(iterator: string, context?: any): _Chain<T>;

/**
* Wrapped type `any[]`.
* @see _.shuffle
**/
shuffle(): _Chain<T>;

/**
* Wrapped type `any[]`.
* @see _.sample
**/
sample<T>(n: number): _Chain<T>;
* Returns a shuffled copy of the wrapped collection, using a version of the Fisher-Yates shuffle.
* @return A shuffled copy of the wrapped collection in a chain wrapper.
**/
shuffle(): _Chain<T, T[]>;

/**
* @see _.sample
**/
sample<T>(): _Chain<T>;
* Produce a random sample from the wrapped collection. Pass a number to return `n` random elements from the
* wrapped collection. Otherwise a single random item will be returned.
* @param n The number of elements to sample from the wrapped collection.
* @return A random sample of `n` elements from the wrapped collection or a single element if `n` is not specified.
* The result will be wrapped in a chain wrapper.
**/
sample(n: number): _Chain<T, T[]>;
sample(): _ChainSingle<T | undefined>;

/**
* Wrapped type `any`.
Expand Down
146 changes: 145 additions & 1 deletion types/underscore/underscore-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,63 @@ _.chain(anyValue)
.find(i => i.findBooleanFunction())
.value();

// $ExpectType { valueProperty: string; } | undefined
_.chain([
{
group: 'a',
subGroup: 1,
value: { valueProperty: 'first' }
},
{
group: 'b',
subGroup: 2,
value: { valueProperty: 'second' }
},
{
group: 'b',
subGroup: 3,
value: { valueProperty: 'third' }
}])
.groupBy(v => v.group)
.filter(g => g.length >= 2)
.flatten()
.where({ subGroup: 2 })
.pluck('value')
.sample()
.value();

// verify that partial objects can be provided without error to where and findWhere for a union type collection
// where no types in the union share the same property names
declare const nonIntersectinglTypeUnion: _.Dictionary<{ one: string; } | { two: number; }>;

// $ExpectType ({ one: string; } | { two: number; })[]
_.chain(nonIntersectinglTypeUnion)
.where({ one: 'one' })
.sample(5)
.value();

// $ExpectType { one: string; } | { two: number; } | undefined
_.chain(nonIntersectinglTypeUnion)
.sample(5)
.findWhere({ two: 2 })
.value();

// verify that both types can be provided without error to where and findWhere for a union type collection where
// two properties in the union have different types
declare const overlappingTypeUnion: _.Dictionary<{ same: string; } | { same: number; }>;

// $ExpectType ({ same: string; } | { same: number; })[]
_.chain(overlappingTypeUnion)
.where({ same: 0 })
.shuffle()
.value();

// $ExpectType { same: string; } | { same: number; } | undefined
_.chain(overlappingTypeUnion)
.shuffle()
.findWhere({ same: 'no' })
.value();

// common testing types and objects
const context = {};

Expand Down Expand Up @@ -619,7 +676,7 @@ declare const extractChainTypes: ChainTypeExtractor;
_(simpleString).map(stringListValueIterator, context); // $ExpectType number[]
extractChainTypes(_.chain(simpleString).map(stringListValueIterator, context)); // $ExpectType ChainType<number[], number>

// function iteratee - collect
// function iteratee - strings - collect
_.collect(simpleString, stringListValueIterator, context); // $ExpectType number[]
_(simpleString).collect(stringListValueIterator, context); // $ExpectType number[]
extractChainTypes(_.chain(simpleString).collect(stringListValueIterator, context)); // $ExpectType ChainType<number[], number>
Expand Down Expand Up @@ -1133,6 +1190,42 @@ declare const extractChainTypes: ChainTypeExtractor;
extractChainTypes(_.chain(stringRecordList).select()); // $ExpectType ChainType<StringRecord[], StringRecord>
}

// where
{
// non-intersecting type union - lists
_.where(nonIntersectingPropertiesList, partialStringRecord); // $ExpectType NonIntersectingProperties[]
_(nonIntersectingPropertiesList).where(partialStringRecord); // $ExpectType NonIntersectingProperties[]
extractChainTypes(_.chain(nonIntersectingPropertiesList).where(partialStringRecord)); // $ExpectType ChainType<NonIntersectingProperties[], NonIntersectingProperties>

// simple type - dictionaries
_.where(stringRecordDictionary, partialStringRecord); // $ExpectType StringRecord[]
_(stringRecordDictionary).where(partialStringRecord); // $ExpectType StringRecord[]
extractChainTypes(_.chain(stringRecordDictionary).where(partialStringRecord)); // $ExpectType ChainType<StringRecord[], StringRecord>

// any
_.where(anyValue, partialStringRecord); // $ExpectType any[]
_(anyValue).where(partialStringRecord); // $ExpectType any[]
extractChainTypes(_.chain(anyValue).where(partialStringRecord)); // $ExpectType ChainType<any[], any>
}

// findWhere
{
// non-intersecting type union - lists
_.findWhere(nonIntersectingPropertiesList, partialStringRecord); // $ExpectType StringRecord | NonIntersectingStringRecord | undefined
_(nonIntersectingPropertiesList).findWhere(partialStringRecord); // $ExpectType StringRecord | NonIntersectingStringRecord | undefined
extractChainTypes(_.chain(nonIntersectingPropertiesList).findWhere(partialStringRecord)); // $ExpectType ChainType<StringRecord | NonIntersectingStringRecord | undefined, never>

// simple type - dictionaries
_.findWhere(stringRecordDictionary, partialStringRecord); // $ExpectType StringRecordOrUndefined
_(stringRecordDictionary).findWhere(partialStringRecord); // $ExpectType StringRecordOrUndefined
extractChainTypes(_.chain(stringRecordDictionary).findWhere(partialStringRecord)); // $ExpectType ChainType<StringRecordOrUndefined, never>

// any
_.findWhere(anyValue, partialStringRecord); // $ExpectType any
_(anyValue).findWhere(partialStringRecord); // $ExpectType any
extractChainTypes(_.chain(anyValue).findWhere(partialStringRecord)); // $ExpectType ChainType<any, any>
}

// reject
{
// function iteratee - lists
Expand Down Expand Up @@ -1228,6 +1321,57 @@ declare const extractChainTypes: ChainTypeExtractor;
_.chain(stringRecordDictionary).groupBy(stringRecordPropertyPath); // // $ExpectType _Chain<StringRecord[], Dictionary<StringRecord[]>>
}

// shuffle
{
// lists
_.shuffle(stringRecordList); // $ExpectType StringRecord[]
_(stringRecordList).shuffle(); // $ExpectType StringRecord[]
extractChainTypes(_.chain(stringRecordList).shuffle()); // $ExpectType ChainType<StringRecord[], StringRecord>

// dictionaries
_.shuffle(stringRecordDictionary); // $ExpectType StringRecord[]
_(stringRecordDictionary).shuffle(); // $ExpectType StringRecord[]
extractChainTypes(_.chain(stringRecordDictionary).shuffle()); // $ExpectType ChainType<StringRecord[], StringRecord>

// strings
_.shuffle(simpleString); // $ExpectType string[]
_(simpleString).shuffle(); // $ExpectType string[]
extractChainTypes(_.chain(simpleString).shuffle()); // $ExpectType ChainType<string[], string>
}

// sample
{
// without n - lists
_.sample(stringRecordList); // $ExpectType StringRecordOrUndefined
_(stringRecordList).sample(); // $ExpectType StringRecordOrUndefined
extractChainTypes(_.chain(stringRecordList).sample()); // $ExpectType ChainType<StringRecordOrUndefined, never>

// without n - dictionaries
_.sample(stringRecordDictionary); // $ExpectType StringRecordOrUndefined
_(stringRecordDictionary).sample(); // $ExpectType StringRecordOrUndefined
extractChainTypes(_.chain(stringRecordDictionary).sample()); // $ExpectType ChainType<StringRecordOrUndefined, never>

// without n - strings
_.sample(simpleString); // $ExpectType string | undefined
_(simpleString).sample(); // $ExpectType string | undefined
extractChainTypes(_.chain(simpleString).sample()); // $ExpectType ChainType<string | undefined, string>

// with n - lists
_.sample(stringRecordList, simpleNumber); // $ExpectType StringRecord[]
_(stringRecordList).sample(simpleNumber); // $ExpectType StringRecord[]
extractChainTypes(_.chain(stringRecordList).sample(simpleNumber)); // $ExpectType ChainType<StringRecord[], StringRecord>

// with n - dictionaries
_.sample(stringRecordDictionary, simpleNumber); // $ExpectType StringRecord[]
_(stringRecordDictionary).sample(simpleNumber); // $ExpectType StringRecord[]
extractChainTypes(_.chain(stringRecordDictionary).sample(simpleNumber)); // $ExpectType ChainType<StringRecord[], StringRecord>

// with n - strings
_.sample(simpleString, simpleNumber); // $ExpectType string[]
_(simpleString).sample(simpleNumber); // $ExpectType string[]
extractChainTypes(_.chain(simpleString).sample(simpleNumber)); // $ExpectType ChainType<string[], string>
}

// Arrays

// flatten
Expand Down