Skip to content

Commit b74a08a

Browse files
feat!: improve type declarations for utils/map-arguments
This change significantly improves the type definition of the mapArguments function, transitioning from broad 'Function' types to specific, generic types and implementing conditional this context based on thisArg presence. BREAKING CHANGE: function signature and return type now more strictly typed The mapArguments function now uses generic types instead of 'Function', and its return type depends on thisArg presence. Users should review and update their usage of mapArguments, particularly: - Ensure provided functions match the new, stricter type requirements - Update any type assertions or checks where mapArguments is used - Pay special attention to contexts where this binding is significant PR-URL: #2050 Closes: #1087 Co-authored-by: Philipp Burckhardt <[email protected]> Co-authored-by: Prajwal Kulkarni <[email protected]> Reviewed-by: Philipp Burckhardt <[email protected]>
1 parent e5b993a commit b74a08a

File tree

2 files changed

+74
-10
lines changed

2 files changed

+74
-10
lines changed

lib/node_modules/@stdlib/utils/map-arguments/docs/types/index.d.ts

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,57 @@
4747
* var out = bar( 1, 2, 3 );
4848
* // returns [ 2, 4, 6 ]
4949
*/
50-
declare function mapArguments( fcn: Function, clbk: Function, thisArg?: any ): Function;
50+
declare function mapArguments<
51+
T extends ( ...args: Array<any> ) => any,
52+
C extends ( this: ThisParameterType<T>, value: Parameters<T>[number], index: number ) => any
53+
>(
54+
fcn: T,
55+
clbk: C
56+
): ( ...args: Parameters<T> ) => ReturnType<T>;
57+
58+
/**
59+
* Returns a function that applies arguments to a provided function after transforming arguments according to a callback function.
60+
*
61+
* ## Notes
62+
*
63+
* - The callback function is provided the following arguments:
64+
*
65+
* - **value**: argument value.
66+
* - **index**: argument index.
67+
*
68+
* @param fcn - input function
69+
* @param clbk - callback function
70+
* @param thisArg - input function context
71+
* @returns function wrapper
72+
*
73+
* @example
74+
* function foo( a, b, c ) {
75+
* return [ a, b, c ];
76+
* }
77+
*
78+
* function clbk( v ) {
79+
* this.count += 1;
80+
* return v * 2;
81+
* }
82+
*
83+
* var thisArg = { 'count': 0 };
84+
* var bar = mapArguments( foo, clbk, thisArg );
85+
*
86+
* var out = bar( 1, 2, 3 );
87+
* // returns [ 2, 4, 6 ]
88+
*
89+
* var count = thisArg.count;
90+
* // returns 3
91+
*/
92+
declare function mapArguments<
93+
T extends ( ...args: Array<any> ) => any,
94+
C extends ( this: ThisParameterType<T>, value: Parameters<T>[number], index: number ) => any,
95+
ThisArg
96+
>(
97+
fcn: T,
98+
clbk: C,
99+
thisArg: ThisArg
100+
): ( this: ThisArg, ...args: Parameters<T> ) => ReturnType<T>;
51101

52102

53103
// EXPORTS //

lib/node_modules/@stdlib/utils/map-arguments/docs/types/test.ts

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,37 @@
1818

1919
import mapArguments = require( './index' );
2020

21-
/**
22-
* Callback function.
23-
*
24-
* @param v - argument
25-
* @returns result
26-
*/
27-
function clbk( v: any ): any {
21+
// FUNCTIONS //
22+
23+
function clbk<T>( v: T ): T {
2824
return v;
2925
}
3026

27+
function stringify( n: number ): string {
28+
return n.toString();
29+
}
30+
31+
function sum( ...numbers: Array<number> ): number {
32+
return numbers.reduce( ( a, b ) => a + b, 0 );
33+
}
34+
35+
function greet( this: { name: string }, greeting: string ): string {
36+
return `${greeting}, ${this.name}!`; // eslint-disable-line no-invalid-this
37+
}
38+
3139

3240
// TESTS //
3341

3442
// The function returns a function...
3543
{
36-
mapArguments( ( x: any, y: any, z: any ): Array<any> => [ x, y, z ], clbk ); // $ExpectType Function
37-
mapArguments( ( x: any, y: any, z: any ): Array<any> => [ x, y, z ], clbk, {} ); // $ExpectType Function
44+
mapArguments( ( x: number, y: number, z: number ): Array<number> => [ x, y, z ], clbk ); // $ExpectType (x: number, y: number, z: number) => number[]
45+
mapArguments( ( x: string, y: string, z: string ): Array<string> => [ x, y, z ], clbk, {} ); // $ExpectType (this: {}, x: string, y: string, z: string) => string[]
46+
mapArguments( ( x: number, y: number ): number => x + y, clbk ); // $ExpectType (x: number, y: number) => number
47+
48+
mapArguments( stringify, ( x: number ) => x * 2 ); // $ExpectType (n: number) => string
49+
mapArguments( sum, ( x: number ) => x * 2 ); // $ExpectType (...args: number[]) => number
50+
51+
mapArguments( greet, ( s: string ) => s.toUpperCase(), { 'name': 'World' } ); // $ExpectType (this: { name: string; }, greeting: string) => string
3852
}
3953

4054
// The compiler throws an error if the function is provided a first argument other than a function...

0 commit comments

Comments
 (0)