Skip to content

Commit 8904b41

Browse files
committed
feat: refactor TypeScript declarations to preserve type information
1 parent d7fc769 commit 8904b41

4 files changed

Lines changed: 128 additions & 13 deletions

File tree

lib/node_modules/@stdlib/utils/curry-right/docs/types/index.d.ts

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,32 @@
1818

1919
// TypeScript Version: 4.1
2020

21+
/**
22+
* Utility type to reverse a tuple type.
23+
*/
24+
type ReverseTuple<T extends Array<any>> = T extends [infer First, ...infer Rest] ? [...ReverseTuple<Rest>, First] : []; // eslint-disable-line @typescript-eslint/no-explicit-any
25+
26+
/**
27+
* Curry function type for curryRight.
28+
*/
29+
type CurryRightFunction<
30+
TThis,
31+
TArgs extends Array<any>, // eslint-disable-line @typescript-eslint/no-explicit-any
32+
TReturn
33+
> = ( this: TThis, ...args: TArgs ) => TReturn;
34+
2135
/**
2236
* Curry function.
2337
*
2438
* @param v - curried function parameter
2539
* @returns partially applied curry function or curried function result
2640
*/
27-
type Closure = ( v: any ) => any;
41+
type Closure<
42+
TArgs extends Array<any>, // eslint-disable-line @typescript-eslint/no-explicit-any
43+
TReturn
44+
> = ReverseTuple<TArgs> extends [infer TFirst, ...infer TRest]
45+
? ( v: TFirst ) => Closure<ReverseTuple<TRest>, TReturn>
46+
: TReturn;
2847

2948
/**
3049
* Transforms a function into a sequence of functions each accepting a single argument.
@@ -50,7 +69,15 @@ type Closure = ( v: any ) => any;
5069
* var sum = f( 2 )( 3 );
5170
* // returns 5
5271
*/
53-
declare function curryRight( fcn: Function, arity: number, thisArg?: any ): Closure;
72+
declare function curryRight<
73+
TThis extends object,
74+
TArgs extends Array<any>, // eslint-disable-line @typescript-eslint/no-explicit-any
75+
TReturn
76+
>(
77+
fcn: CurryRightFunction<TThis, TArgs, TReturn>,
78+
arity: number,
79+
thisArg?: TThis
80+
): Closure<TArgs, TReturn>;
5481

5582
/**
5683
* Transforms a function into a sequence of functions each accepting a single argument.
@@ -74,7 +101,14 @@ declare function curryRight( fcn: Function, arity: number, thisArg?: any ): Clos
74101
* var sum = f( 2 )( 3 );
75102
* // returns 5
76103
*/
77-
declare function curryRight( fcn: Function, thisArg?: any ): Closure;
104+
declare function curryRight<
105+
TThis extends object,
106+
TArgs extends Array<any>, // eslint-disable-line @typescript-eslint/no-explicit-any
107+
TReturn
108+
>(
109+
fcn: CurryRightFunction<TThis, TArgs, TReturn>,
110+
thisArg?: TThis
111+
): Closure<TArgs, TReturn>;
78112

79113

80114
// EXPORTS //

lib/node_modules/@stdlib/utils/curry-right/docs/types/test.ts

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,23 @@ import curryRight = require( './index' );
2323

2424
// The function returns a function...
2525
{
26-
curryRight( ( x: number, y: number ): number => x + y ); // $ExpectType Closure
27-
curryRight( ( x: number, y: number ): number => x + y, 2 ); // $ExpectType Closure
28-
curryRight( ( x: number, y: number ): number => x + y, 2, {} ); // $ExpectType Closure
26+
curryRight( ( x: number, y: number ): number => x + y ); // $ExpectType (v: number) => (v: number) => number
27+
curryRight( ( x: number, y: number ): number => x + y, 2 ); // $ExpectType (v: number) => (v: number) => number
28+
curryRight( ( x: number, y: number ): number => x + y, 2, {} ); // $ExpectType (v: number) => (v: number) => number
29+
curryRight( ( x: string, y: string ): string => x + y, {} ); // $ExpectType (v: string) => (v: string) => string
30+
curryRight( ( x: string, y: string ): string => x + y, 2, {} ); // $ExpectType (v: string) => (v: string) => string
31+
curryRight( ( str: string, n: number ): string => str.substring( n ) ); // $ExpectType (v: number) => (v: string) => string
32+
33+
const cxt = {
34+
'count': 0,
35+
'multiply': function multiply( this: { count: number }, x: number, y: number ): number {
36+
this.count += 1; // eslint-disable-line no-invalid-this
37+
return x * y;
38+
}
39+
};
40+
curryRight( cxt.multiply ); // $ExpectType (v: number) => (v: number) => number
41+
curryRight( cxt.multiply, 2 ); // $ExpectType (v: number) => (v: number) => number
42+
curryRight( cxt.multiply, 2, { 'count': 2 } ); // $ExpectType (v: number) => (v: number) => number
2943
}
3044

3145
// The compiler throws an error if the function is provided a first argument other than a function...
@@ -38,6 +52,19 @@ import curryRight = require( './index' );
3852
curryRight( 'abc' ); // $ExpectError
3953
}
4054

55+
// The compiler throws an error if the function is provided a this argument which does not constitute a valid `this` context...
56+
{
57+
const cxt = {
58+
'count': 0,
59+
'multiply': function multiply( this: { count: number }, x: number, y: number ): number {
60+
this.count += 1; // eslint-disable-line no-invalid-this
61+
return x * y;
62+
}
63+
};
64+
curryRight( cxt.multiply, { 'COUNT': 2 } ); // $ExpectError
65+
curryRight( cxt.multiply, 2, {} ); // $ExpectError
66+
}
67+
4168
// The compiler throws an error if the function is provided more than three arguments...
4269
{
4370
curryRight( ( x: number, y: number ): number => x + y, 2, {}, 4 ); // $ExpectError

lib/node_modules/@stdlib/utils/curry/docs/types/index.d.ts

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,27 @@
1818

1919
// TypeScript Version: 4.1
2020

21+
/**
22+
* Curry function type.
23+
*/
24+
type CurryFunction<
25+
TThis,
26+
TArgs extends Array<any>, // eslint-disable-line @typescript-eslint/no-explicit-any
27+
TReturn
28+
> = ( this: TThis, ...args: TArgs ) => TReturn;
29+
2130
/**
2231
* Curry function.
2332
*
2433
* @param v - curried function parameter
2534
* @returns partially applied curry function or curried function result
2635
*/
27-
type Closure = ( v: any ) => any;
36+
type Closure<
37+
TArgs extends Array<any>, // eslint-disable-line @typescript-eslint/no-explicit-any
38+
TReturn
39+
> = TArgs extends [infer TFirst, ...infer TRest]
40+
? ( v: TFirst ) => Closure<TRest, TReturn>
41+
: TReturn;
2842

2943
/**
3044
* Transforms a function into a sequence of functions each accepting a single argument.
@@ -49,7 +63,15 @@ type Closure = ( v: any ) => any;
4963
* var sum = f( 2 )( 3 );
5064
* // returns 5
5165
*/
52-
declare function curry( fcn: Function, arity: number, thisArg?: any ): Closure;
66+
declare function curry<
67+
TThis extends object,
68+
TArgs extends Array<any>, // eslint-disable-line @typescript-eslint/no-explicit-any
69+
TReturn
70+
>(
71+
fcn: CurryFunction<TThis, TArgs, TReturn>,
72+
arity: number,
73+
thisArg?: TThis
74+
): Closure<TArgs, TReturn>;
5375

5476
/**
5577
* Transforms a function into a sequence of functions each accepting a single argument.
@@ -72,7 +94,14 @@ declare function curry( fcn: Function, arity: number, thisArg?: any ): Closure;
7294
* var sum = f( 2 )( 3 );
7395
* // returns 5
7496
*/
75-
declare function curry( fcn: Function, thisArg?: any ): Closure;
97+
declare function curry<
98+
TThis extends object,
99+
TArgs extends Array<any>, // eslint-disable-line @typescript-eslint/no-explicit-any
100+
TReturn
101+
>(
102+
fcn: CurryFunction<TThis, TArgs, TReturn>,
103+
thisArg?: TThis
104+
): Closure<TArgs, TReturn>;
76105

77106

78107
// EXPORTS //

lib/node_modules/@stdlib/utils/curry/docs/types/test.ts

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,22 @@ import curry = require( './index' );
2323

2424
// The function returns a function...
2525
{
26-
curry( ( x: number, y: number ): number => x + y ); // $ExpectType Closure
27-
curry( ( x: number, y: number ): number => x + y, 2 ); // $ExpectType Closure
28-
curry( ( x: number, y: number ): number => x + y, {} ); // $ExpectType Closure
29-
curry( ( x: number, y: number ): number => x + y, 2, {} ); // $ExpectType Closure
26+
curry( ( x: number, y: number ): number => x + y ); // $ExpectType (v: number) => (v: number) => number
27+
curry( ( x: number, y: number ): number => x + y, 2 ); // $ExpectType (v: number) => (v: number) => number
28+
curry( ( x: string, y: string ): string => x + y, {} ); // $ExpectType (v: string) => (v: string) => string
29+
curry( ( x: string, y: string ): string => x + y, 2, {} ); // $ExpectType (v: string) => (v: string) => string
30+
curry( ( str: string, n: number ): string => str.substring( n ) ); // $ExpectType (v: string) => (v: number) => string
31+
32+
const cxt = {
33+
'count': 0,
34+
'multiply': function multiply( this: { count: number }, x: number, y: number ): number {
35+
this.count += 1; // eslint-disable-line no-invalid-this
36+
return x * y;
37+
}
38+
};
39+
curry( cxt.multiply ); // $ExpectType (v: number) => (v: number) => number
40+
curry( cxt.multiply, 2 ); // $ExpectType (v: number) => (v: number) => number
41+
curry( cxt.multiply, 2, { 'count': 2 } ); // $ExpectType (v: number) => (v: number) => number
3042
}
3143

3244
// The compiler throws an error if the function is provided a first argument other than a function...
@@ -39,6 +51,19 @@ import curry = require( './index' );
3951
curry( 'abc' ); // $ExpectError
4052
}
4153

54+
// The compiler throws an error if the function is provided a third argument which does not constitute a valid `this` context...
55+
{
56+
const cxt = {
57+
'count': 0,
58+
'multiply': function multiply( this: { count: number }, x: number, y: number ): number {
59+
this.count += 1; // eslint-disable-line no-invalid-this
60+
return x * y;
61+
}
62+
};
63+
curry( cxt.multiply, { 'COUNT': 2 } ); // $ExpectError
64+
curry( cxt.multiply, 2, {} ); // $ExpectError
65+
}
66+
4267
// The compiler throws an error if the function is provided more than three arguments...
4368
{
4469
curry( ( x: number, y: number ): number => x + y, 2, {}, 4 ); // $ExpectError

0 commit comments

Comments
 (0)