Skip to content

Commit ec4730b

Browse files
refactor: improve type specificity for utils/group-own
PR-URL: #1436 Closes: #1085 --------- Signed-off-by: Shubh Mehta <[email protected]> Co-authored-by: Philipp Burckhardt <[email protected]> Reviewed-by: Philipp Burckhardt <[email protected]>
1 parent 2b6f932 commit ec4730b

File tree

2 files changed

+125
-34
lines changed

2 files changed

+125
-34
lines changed

lib/node_modules/@stdlib/utils/group-own/docs/types/index.d.ts

Lines changed: 102 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,15 @@ interface Options {
3838
*
3939
* @returns group key
4040
*/
41-
type Nullary = () => string | symbol;
41+
type Nullary<K extends string | symbol> = () => K;
4242

4343
/**
4444
* Specifies which group a property belongs to.
4545
*
4646
* @param value - object value
4747
* @returns group key
4848
*/
49-
type Unary = ( value: any ) => string | symbol;
49+
type Unary<V, K extends string | symbol> = ( value: V ) => K;
5050

5151
/**
5252
* Specifies which group a property belongs to.
@@ -55,7 +55,7 @@ type Unary = ( value: any ) => string | symbol;
5555
* @param key - object key
5656
* @returns group key
5757
*/
58-
type Binary = ( value: any, key: string | symbol ) => string | symbol;
58+
type Binary<V, K extends string | symbol> = ( value: V, key: string ) => K;
5959

6060
/**
6161
* Specifies which group a property belongs to.
@@ -64,7 +64,7 @@ type Binary = ( value: any, key: string | symbol ) => string | symbol;
6464
* @param key - object key
6565
* @returns group key
6666
*/
67-
type Indicator = Nullary | Unary | Binary;
67+
type Indicator<V, K extends string | symbol> = Nullary<K> | Unary<V, K> | Binary<V, K>;
6868

6969
/**
7070
* Groups an object's own property values according to an indicator function.
@@ -93,15 +93,18 @@ type Indicator = Nullary | Unary | Binary;
9393
* return v[ 0 ];
9494
* }
9595
* var obj = {
96-
* 'a': 'beep',
97-
* 'b': 'boop',
98-
* 'c': 'foo',
99-
* 'd': 'bar'
96+
* 'a': 'apple',
97+
* 'b': 'banana',
98+
* 'c': 'cherry',
99+
* 'd': 'date'
100100
* };
101101
* var out = groupOwn( obj, indicator );
102-
* // e.g., returns { 'b': [ 'beep', 'boop', 'bar' ], 'f': [ 'foo' ] }
102+
* // e.g., returns { 'a': [ 'apple' ], 'b': [ 'banana' ], 'c': [ 'cherry' ], 'd': [ 'date' ] }
103103
*/
104-
declare function groupOwn( obj: any, indicator: Indicator ): any;
104+
declare function groupOwn<T extends object, K extends string | symbol>(
105+
obj: T,
106+
indicator: Indicator<T[keyof T], K>
107+
): { [P in K]: Array<T[keyof T]> };
105108

106109
/**
107110
* Groups an object's own property values according to an indicator function.
@@ -124,7 +127,7 @@ declare function groupOwn( obj: any, indicator: Indicator ): any;
124127
* @param obj - input object
125128
* @param options - function options
126129
* @param options.thisArg - execution context
127-
* @param options.returns - if `values`, values are returned; if `keys`, keys are returned; if `*`, both keys and values are returned (default: 'values')
130+
* @param options.returns - if `'values'`, values are returned; if `'indices'`, indices are returned; if `'*'`, both indices and values are returned (default: 'values')
128131
* @param indicator - indicator function indicating which group an element in the input object belongs to
129132
* @returns group results
130133
*
@@ -133,47 +136,116 @@ declare function groupOwn( obj: any, indicator: Indicator ): any;
133136
* return v[ 0 ];
134137
* }
135138
* var obj = {
136-
* 'a': 'beep',
137-
* 'b': 'boop',
138-
* 'c': 'foo',
139-
* 'd': 'bar'
139+
* 'a': 'apple',
140+
* 'b': 'banana',
141+
* 'c': 'cherry',
142+
* 'd': 'date'
140143
* };
141-
* var out = groupOwn( obj, indicator );
142-
* // e.g., returns { 'b': [ 'beep', 'boop', 'bar' ], 'f': [ 'foo' ] }
144+
* var opts = {
145+
* 'returns': 'indices'
146+
* };
147+
* var out = groupOwn( obj, opts, indicator );
148+
* // e.g., returns { 'a': [ 'a' ], 'b': [ 'b' ], 'c': [ 'c' ], 'd': [ 'd' ] }
149+
*/
150+
declare function groupOwn<T extends object, K extends string | symbol>(
151+
obj: T,
152+
options: Options & { returns: 'indices' },
153+
indicator: Indicator<T[keyof T], K>
154+
): { [P in K]: Array<keyof T> };
155+
156+
/**
157+
* Groups an object's own property values according to an indicator function.
158+
*
159+
* ## Notes
160+
*
161+
* - When invoked, the indicator function is provided two arguments:
162+
*
163+
* - `value`: object value
164+
* - `key`: object key
165+
*
166+
* - The value returned by an indicator function should be a value which can be serialized as an object key.
167+
*
168+
* - If provided an empty object, the function returns an empty object.
169+
*
170+
* - The function iterates over an object's own properties.
171+
*
172+
* - Key iteration order is **not** guaranteed, and, thus, result order is **not** guaranteed.
173+
*
174+
* @param obj - input object
175+
* @param options - function options
176+
* @param options.thisArg - execution context
177+
* @param options.returns - if `'values'`, values are returned; if `'indices'`, indices are returned; if `'*'`, both indices and values are returned (default: 'values')
178+
* @param indicator - indicator function indicating which group an element in the input object belongs to
179+
* @returns group results
143180
*
144181
* @example
145182
* function indicator( v ) {
146183
* return v[ 0 ];
147184
* }
148185
* var obj = {
149-
* 'a': 'beep',
150-
* 'b': 'boop',
151-
* 'c': 'foo',
152-
* 'd': 'bar'
186+
* 'a': 'apple',
187+
* 'b': 'banana',
188+
* 'c': 'cherry',
189+
* 'd': 'date'
153190
* };
154191
* var opts = {
155-
* 'returns': 'keys'
192+
* 'returns': '*'
156193
* };
157194
* var out = groupOwn( obj, opts, indicator );
158-
* // e.g., returns { 'b': [ 'a', 'b', 'd' ], 'f': [ 'c' ] }
195+
* // e.g., returns { 'a': [ [ 'a', 'apple' ] ], 'b': [ [ 'b', 'banana' ] ], 'c': [ [ 'c', 'cherry' ] ], 'd': [ [ 'd', 'date' ] ] }
196+
*/
197+
declare function groupOwn<T extends object, K extends string | symbol>(
198+
obj: T,
199+
options: Options & { returns: '*' },
200+
indicator: Indicator<T[keyof T], K>
201+
): { [P in K]: Array<[keyof T, T[keyof T]]> };
202+
203+
/**
204+
* Groups an object's own property values according to an indicator function.
205+
*
206+
* ## Notes
207+
*
208+
* - When invoked, the indicator function is provided two arguments:
209+
*
210+
* - `value`: object value
211+
* - `key`: object key
212+
*
213+
* - The value returned by an indicator function should be a value which can be serialized as an object key.
214+
*
215+
* - If provided an empty object, the function returns an empty object.
216+
*
217+
* - The function iterates over an object's own properties.
218+
*
219+
* - Key iteration order is **not** guaranteed, and, thus, result order is **not** guaranteed.
220+
*
221+
* @param obj - input object
222+
* @param options - function options
223+
* @param options.thisArg - execution context
224+
* @param options.returns - if `'values'`, values are returned; if `'indices'`, indices are returned; if `'*'`, both indices and values are returned (default: 'values')
225+
* @param indicator - indicator function indicating which group an element in the input object belongs to
226+
* @returns group results
159227
*
160228
* @example
161229
* function indicator( v ) {
162230
* return v[ 0 ];
163231
* }
164232
* var obj = {
165-
* 'a': 'beep',
166-
* 'b': 'boop',
167-
* 'c': 'foo',
168-
* 'd': 'bar'
233+
* 'a': 'apple',
234+
* 'b': 'banana',
235+
* 'c': 'cherry',
236+
* 'd': 'date'
169237
* };
170238
* var opts = {
171-
* 'returns': '*'
239+
* 'returns': 'values'
172240
* };
173241
* var out = groupOwn( obj, opts, indicator );
174-
* // e.g., returns { 'b': [ [ 'a', 'beep' ], [ 'b', 'boop' ], [ 'd', 'bar' ] ], 'f': [ [ 'c', 'foo' ] ] }
242+
* // e.g., returns { 'a': [ 'apple' ], 'b': [ 'banana' ], 'c': [ 'cherry' ], 'd': [ 'date' ] }
175243
*/
176-
declare function groupOwn( obj: any, options: Options, indicator: Indicator ): any;
244+
declare function groupOwn<T extends object, K extends string | symbol>(
245+
obj: T,
246+
options: Options & { returns?: 'values' },
247+
indicator: Indicator<T[keyof T], K>
248+
): { [P in K]: Array<T[keyof T]> };
177249

178250

179251
// EXPORTS //

lib/node_modules/@stdlib/utils/group-own/docs/types/test.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,31 @@ class Foo {
4646
// The function returns an object...
4747
{
4848
const obj = new Foo();
49-
groupOwn( obj, indicator ); // $ExpectType any
50-
groupOwn( {}, indicator ); // $ExpectType any
49+
groupOwn( obj, indicator ); // $ExpectType { [x: string]: string[]; }
50+
groupOwn( {}, indicator ); // $ExpectType { [x: string]: never[]; }
5151
const opts = {
52-
'returns': 'indices' as 'indices'
52+
'returns': 'indices' as const
5353
};
54-
groupOwn( obj, opts, indicator ); // $ExpectType any
54+
groupOwn( obj, opts, indicator ); // $ExpectType { [x: string]: (keyof Foo)[]; }
55+
56+
const opts2 = {
57+
'returns': 'values' as const
58+
};
59+
groupOwn( obj, opts2, indicator ); // $ExpectType { [x: string]: string[]; }
60+
61+
const opts3 = {
62+
'returns': '*' as const
63+
};
64+
groupOwn( obj, opts3, indicator ); // $ExpectType { [x: string]: [keyof Foo, string][]; }
65+
66+
const obj2 = {
67+
'beep': 'boop',
68+
'foo': 'bar'
69+
} as const;
70+
71+
groupOwn( obj2, opts, indicator ); // $ExpectType { [x: string]: ("beep" | "foo")[]; }
72+
groupOwn( obj2, opts2, indicator ); // $ExpectType { [x: string]: ("boop" | "bar")[]; }
73+
groupOwn( obj2, opts3, indicator ); // $ExpectType { [x: string]: ["beep" | "foo", "boop" | "bar"][]; }
5574
}
5675

5776
// The compiler throws an error if the function is provided a last argument which is not a function...

0 commit comments

Comments
 (0)