3
3
4
4
type Property = string | number | symbol ;
5
5
6
+ type PromiseLikeOrNot < T > = PromiseLike < T > | T ;
7
+
8
+ type Unpromise < T > = T extends PromiseLikeOrNot < infer U > ? U : T ;
9
+
10
+ type Parameters < T > = T extends ( ... args : infer T ) => any ? T : never ;
11
+ type ReturnType < T > = T extends ( ... args : any [ ] ) => infer T ? T : never ;
12
+
6
13
interface EHandler < T > {
7
14
get ?: ( p : T , name : Property ) => any ;
8
15
applyMethod ?: ( p : T , name ?: Property , args : unknown [ ] ) => any ;
@@ -28,18 +35,31 @@ interface HandledPromiseConstructor {
28
35
29
36
export const HandledPromise : HandledPromiseConstructor ;
30
37
31
- interface ESingleMethod < R = Promise < unknown > > {
32
- ( ... args : unknown [ ] ) => R ;
33
- readonly [ prop : string ] : ( ...args : unknown [ ] ) => R ;
38
+ /* Types for E proxy calls. */
39
+ type ESingleMethod < T > = {
40
+ readonly [ P in keyof T ] : ( ...args : Parameters < T [ P ] > ) => Promise < ReturnType < T [ P ] > > ;
34
41
}
35
-
36
- interface ESingleGet < R = Promise < unknown > > {
37
- readonly [ prop : string ] : R ;
42
+ type ESingleCall < T > = T extends Function ?
43
+ ( ( ...args : Parameters < T > ) => Promise < ReturnType < T > > ) & ESingleMethod < T > :
44
+ ESingleMethod < T > ;
45
+ type ESingleGet < T > = {
46
+ readonly [ P in keyof T ] : Promise < T [ P ] > ;
47
+ }
48
+
49
+ /* Same types for send-only. */
50
+ type ESingleMethodOnly < T > = {
51
+ readonly [ P in keyof T ] : ( ...args : Parameters < T [ P ] > ) => void ;
52
+ }
53
+ type ESingleCallOnly < T > = T extends Function ?
54
+ ( ( ...args : Parameters < T > ) => void ) & ESingleMethodOnly < T > :
55
+ ESingleMethodOnly < T > ;
56
+ type ESingleGetOnly < T > = {
57
+ readonly [ P in keyof T ] : void ;
38
58
}
39
59
40
60
interface ESendOnly {
41
- ( x : unknown ) : ESingleMethod < void > ;
42
- readonly G ( x : unknown ) : ESingleGet < void > ;
61
+ < T > ( x : T ) : ESingleCallOnly < Unpromise < T > , void > ;
62
+ readonly G < T > ( x : T ) : ESingleGetOnly < Unpromise < T > > ;
43
63
}
44
64
45
65
interface EProxy {
@@ -49,10 +69,10 @@ interface EProxy {
49
69
* whatever 'x' designates (or resolves to) in a future turn, not this
50
70
* one.
51
71
*
52
- * @param {* } x target for method call
53
- * @returns {ESingleMethod } method call proxy
72
+ * @param {* } x target for method/function call
73
+ * @returns {ESingleCall } method/function call proxy
54
74
*/
55
- ( x : unknown ) : ESingleMethod ;
75
+ < T > ( x : T ) : ESingleCall < Unpromise < T > > ;
56
76
/**
57
77
* E.G(x) returns a proxy on which you can get arbitrary properties.
58
78
* Each of these properties returns a promise for the property. The promise
@@ -62,16 +82,16 @@ interface EProxy {
62
82
* @param {* } x target for property get
63
83
* @returns {ESingleGet } property get proxy
64
84
*/
65
- readonly G ( x : unknown ) : ESingleGet ;
85
+ readonly G < T > ( x : T ) : ESingleGet < Unpromise < T > > ;
66
86
67
87
/**
68
88
* E.when(x, res, rej) is equivalent to HandledPromise.resolve(x).then(res, rej)
69
89
*/
70
- readonly when (
71
- x : unknown ,
72
- onfulfilled ?: ( value : unknown ) => unknown | PromiseLike < unknown > ,
90
+ readonly when < T > (
91
+ x : T ,
92
+ onfulfilled ?: ( value : Unpromise < T > ) => any | PromiseLike < any > ,
73
93
onrejected ?: ( reason : any ) => PromiseLike < never > ,
74
- ) : Promise < unknown > ;
94
+ ) : Promise < any > ;
75
95
76
96
/**
77
97
* E.sendOnly returns a proxy similar to E, but for which the results
0 commit comments