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,34 @@ 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 ;
38
+ }
39
+
40
+ type BindProps < P > = {
41
+ [ K in keyof P ] ?: ( props : ReadOnly < BoundProps < P > > ) => Promise < P [ K ] >
42
+ } ;
43
+
44
+ type BoundProps < P > = PageProps & BindProps < P > ;
45
+
46
+ interface BindStateNormal < P > {
47
+ data : { [ K in keyof P ] : P [ K ] } ;
48
+ error : null ;
32
49
}
33
50
34
- interface BindState {
35
- data : { [ key : string ] : string } ;
51
+ interface BindStateError {
52
+ data : null ;
36
53
error : string ;
37
54
}
38
55
56
+ type BindState < P > = BindStateNormal < P > | BindStateError ;
57
+
39
58
/**
40
59
* This react HOC can be used to bind result of some async
41
60
* methods to props of the given component (C).
@@ -48,8 +67,8 @@ interface BindState {
48
67
* }
49
68
* });
50
69
*/
51
- function bind ( C , bindProps : BindProps ) {
52
- return class extends Component < any , BindState > {
70
+ function bind < P > ( C : ComponentConstructor < P , { } > , bindProps : BindProps < P > ) {
71
+ return class extends Component < BoundProps < P > , BindState < P > > {
53
72
state = { data : null , error : null } ;
54
73
prevMatches = null ;
55
74
componentRef ;
@@ -61,7 +80,7 @@ function bind(C, bindProps: BindProps) {
61
80
async loadData ( ) {
62
81
if ( equal ( this . props . matches , this . prevMatches ) ) return ;
63
82
this . prevMatches = this . props . matches ;
64
- const data = { } ;
83
+ const data : Partial < P > = { } ;
65
84
for ( const key in bindProps ) {
66
85
if ( ! bindProps [ key ] ) continue ;
67
86
try {
@@ -71,7 +90,7 @@ function bind(C, bindProps: BindProps) {
71
90
return ;
72
91
}
73
92
}
74
- this . setState ( { data, error : null } ) ;
93
+ this . setState ( { data : data as P , error : null } ) ;
75
94
}
76
95
77
96
render ( ) {
0 commit comments