1313 limitations under the License.
1414 */
1515
16- import { Component , h } from "preact" ;
16+ import { Component , ComponentConstructor , h } from "preact" ;
1717import * as db from "./db" ;
1818import { push , Router } from "./router" ;
1919import * as types from "./types" ;
@@ -28,15 +28,34 @@ import { Notebook } from "./components/notebook";
2828import { Profile } from "./components/profile" ;
2929import { Recent } from "./components/recent" ;
3030
31- interface BindProps {
32- [ key : string ] : ( props : any ) => Promise < any > ;
31+ type Partial < T > = { [ K in keyof T ] ?: T [ K ] } ;
32+
33+ type ReadOnly < T > = { readonly [ K in keyof T ] : T [ K ] } ;
34+
35+ interface PageProps {
36+ path : string ;
37+ matches ?: { [ key : string ] : string } ;
38+ onReady ?: ( ) => void ;
39+ }
40+
41+ type BindProps < P > = {
42+ [ K in keyof P ] ?: ( props : ReadOnly < BoundProps < P > > ) => Promise < P [ K ] >
43+ } ;
44+
45+ type BoundProps < P > = PageProps & BindProps < P > ;
46+
47+ interface BindStateNormal < P > {
48+ data : { [ K in keyof P ] : P [ K ] } ;
49+ error : null ;
3350}
3451
35- interface BindState {
36- data : { [ key : string ] : string } ;
52+ interface BindStateError {
53+ data : null ;
3754 error : string ;
3855}
3956
57+ type BindState < P > = BindStateNormal < P > | BindStateError ;
58+
4059/**
4160 * This react HOC can be used to bind result of some async
4261 * methods to props of the given component (C).
@@ -49,8 +68,8 @@ interface BindState {
4968 * }
5069 * });
5170 */
52- function bind ( C , bindProps : BindProps ) {
53- return class extends Component < any , BindState > {
71+ function bind < P > ( C : ComponentConstructor < P , { } > , bindProps : BindProps < P > ) {
72+ return class extends Component < BoundProps < P > , BindState < P > > {
5473 state = { data : null , error : null } ;
5574 prevMatches = null ;
5675 componentRef ;
@@ -62,7 +81,7 @@ function bind(C, bindProps: BindProps) {
6281 async loadData ( ) {
6382 if ( equal ( this . props . matches , this . prevMatches ) ) return ;
6483 this . prevMatches = this . props . matches ;
65- const data = { } ;
84+ const data : Partial < P > = { } ;
6685 for ( const key in bindProps ) {
6786 if ( ! bindProps [ key ] ) continue ;
6887 try {
@@ -72,7 +91,7 @@ function bind(C, bindProps: BindProps) {
7291 return ;
7392 }
7493 }
75- this . setState ( { data, error : null } ) ;
94+ this . setState ( { data : data as P , error : null } ) ;
7695 }
7796
7897 render ( ) {
@@ -170,7 +189,7 @@ export const NotebookPage = bind(Notebook, {
170189 }
171190} ) ;
172191
173- export const HomePage = bind ( Home , { } ) ;
192+ export const HomePage = bind ( Home as any , { } ) ;
174193// tslint:enable:variable-name
175194
176195export interface AppState {
0 commit comments