diff --git a/src/app.tsx b/src/app.tsx index 85d32971..7a0a827a 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -13,7 +13,7 @@ limitations under the License. */ -import { Component, h } from "preact"; +import { Component, ComponentConstructor, h } from "preact"; import * as db from "./db"; import { push, Router } from "./router"; import * as types from "./types"; @@ -27,15 +27,32 @@ import { Notebook } from "./components/notebook"; import { Profile } from "./components/profile"; import { Recent } from "./components/recent"; -interface BindProps { - [key: string]: (props: any) => Promise; +type Partial = { [K in keyof T]?: T[K] }; + +type ReadOnly = { readonly [K in keyof T]: T[K] }; + +interface PageProps { + path: string; + matches?: { [key: string]: string }; + onReady?: () => void; } -interface BindState { - data: { [key: string]: string }; +type BindProps

= { + [K in keyof P]?: (props: ReadOnly & PageProps>) => Promise +}; + +interface BindStateNormal { + data: { [K in keyof S]: S[K] }; + error: null; +} + +interface BindStateError { + data: null; error: string; } +type BindState = BindStateNormal | BindStateError; + /** * This react HOC can be used to bind result of some async * methods to props of the given component (C). @@ -48,8 +65,8 @@ interface BindState { * } * }); */ -function bind(C, bindProps: BindProps) { - return class extends Component { +function bind

(C: ComponentConstructor, bindProps: BindProps

) { + return class extends Component & PageProps, BindState

> { state = { data: null, error: null }; prevMatches = null; componentRef; @@ -61,7 +78,7 @@ function bind(C, bindProps: BindProps) { async loadData() { if (equal(this.props.matches, this.prevMatches)) return; this.prevMatches = this.props.matches; - const data = {}; + const data: Partial

= {}; for (const key in bindProps) { if (!bindProps[key]) continue; try { @@ -71,7 +88,7 @@ function bind(C, bindProps: BindProps) { return; } } - this.setState({ data, error: null }); + this.setState({ data: data as P, error: null }); } render() { diff --git a/src/nb_test.ts b/src/nb_test.ts index e72f919f..95907ee4 100644 --- a/src/nb_test.ts +++ b/src/nb_test.ts @@ -185,7 +185,7 @@ function resetPage() { function renderProfile(profileUid: string) { const promise = createResolvable(); resetPage(); - const el = h(ProfilePage, { + const el = h(ProfilePage as any, { matches: { userId: profileUid }, @@ -199,7 +199,7 @@ async function renderAnonNotebook(): Promise { const promise = createResolvable(); resetPage(); let notebookRoot; - const el = h(NotebookPage, { + const el = h(NotebookPage as any, { matches: { nbId: "default" },