13
13
limitations under the License.
14
14
*/
15
15
16
- import { Component , h } from "preact" ;
16
+ import { Component , ComponentConstructor , h } from "preact" ;
17
17
import * as db from "./db" ;
18
18
import { push , Router } from "./router" ;
19
19
import * as types from "./types" ;
@@ -27,15 +27,32 @@ import { Notebook } from "./components/notebook";
27
27
import { Profile } from "./components/profile" ;
28
28
import { Recent } from "./components/recent" ;
29
29
30
- interface BindProps {
31
- [ key : string ] : ( props : any ) => Promise < any > ;
30
+ type Partial < T > = { [ K in keyof T ] ?: T [ K ] } ;
31
+
32
+ type ReadOnly < T > = { readonly [ K in keyof T ] : T [ K ] } ;
33
+
34
+ interface PageProps {
35
+ path : string ;
36
+ matches ?: { [ key : string ] : string } ;
37
+ onReady ?: ( ) => void ;
32
38
}
33
39
34
- interface BindState {
35
- data : { [ key : string ] : string } ;
40
+ type BindProps < P > = {
41
+ [ K in keyof P ] ?: ( props : ReadOnly < Partial < P > & PageProps > ) => Promise < P [ K ] >
42
+ } ;
43
+
44
+ interface BindStateNormal < S > {
45
+ data : { [ K in keyof S ] : S [ K ] } ;
46
+ error : null ;
47
+ }
48
+
49
+ interface BindStateError {
50
+ data : null ;
36
51
error : string ;
37
52
}
38
53
54
+ type BindState < S > = BindStateNormal < S > | BindStateError ;
55
+
39
56
/**
40
57
* This react HOC can be used to bind result of some async
41
58
* methods to props of the given component (C).
@@ -48,8 +65,8 @@ interface BindState {
48
65
* }
49
66
* });
50
67
*/
51
- function bind ( C , bindProps : BindProps ) {
52
- return class extends Component < any , BindState > {
68
+ function bind < P > ( C : ComponentConstructor < P , { } > , bindProps : BindProps < P > ) {
69
+ return class extends Component < Partial < P > & PageProps , BindState < P > > {
53
70
state = { data : null , error : null } ;
54
71
prevMatches = null ;
55
72
componentRef ;
@@ -61,7 +78,7 @@ function bind(C, bindProps: BindProps) {
61
78
async loadData ( ) {
62
79
if ( equal ( this . props . matches , this . prevMatches ) ) return ;
63
80
this . prevMatches = this . props . matches ;
64
- const data = { } ;
81
+ const data : Partial < P > = { } ;
65
82
for ( const key in bindProps ) {
66
83
if ( ! bindProps [ key ] ) continue ;
67
84
try {
@@ -71,7 +88,7 @@ function bind(C, bindProps: BindProps) {
71
88
return ;
72
89
}
73
90
}
74
- this . setState ( { data, error : null } ) ;
91
+ this . setState ( { data : data as P , error : null } ) ;
75
92
}
76
93
77
94
render ( ) {
0 commit comments