diff --git a/src/app/app.ts b/src/app/app.ts index a4e8f84d..ff8d9d13 100644 --- a/src/app/app.ts +++ b/src/app/app.ts @@ -1,4 +1,4 @@ -import { Component } from "../component/component"; +import { Component, ComponentConstructor } from "../component/component"; import { ComponentNode } from "../component/component_node"; import { MountOptions } from "../component/fibers"; import { Scheduler } from "../component/scheduler"; @@ -11,9 +11,9 @@ export interface Env { [key: string]: any; } -export interface AppConfig extends TemplateSetConfig { - env?: Env; - props?: any; +export interface AppConfig
extends TemplateSetConfig {
+ props?: P;
+ env?: E;
}
export const DEV_MSG = `Owl is running in 'dev' mode.
@@ -21,25 +21,29 @@ export const DEV_MSG = `Owl is running in 'dev' mode.
This is not suitable for production use.
See https://github.com/odoo/owl/blob/master/doc/reference/config.md#mode for more information.`;
-export class App ;
+ props: P;
+ env: E;
scheduler = new Scheduler();
- root: ComponentNode | null = null;
+ root: ComponentNode | null = null;
- constructor(Root: T, config: AppConfig = {}) {
+ constructor(Root: ComponentConstructor , config: AppConfig = {}) {
super(config);
this.Root = Root;
if (config.dev) {
console.info(DEV_MSG);
}
const descrs = Object.getOwnPropertyDescriptors(config.env || {});
- this.env = Object.freeze(Object.defineProperties({}, descrs));
- this.props = config.props || {};
+ this.env = Object.freeze(Object.defineProperties({}, descrs)) as E;
+ this.props = config.props || ({} as P);
}
- mount(target: HTMLElement, options?: MountOptions): Promise ,
target: HTMLElement,
- config: AppConfig & MountOptions = {}
-): Promise & MountOptions = {}
+): Promise = (new (
+ props: P,
+ env: E,
+ node: ComponentNode
+) => Component ) &
+ StaticComponentProperties;
+
export class Component implements VNode ;
bdom: BDom | null = null;
status: STATUS = STATUS.NEW;
@@ -99,7 +97,7 @@ export class ComponentNode , props: P, app: App, parent?: ComponentNode) {
currentNode = this;
this.app = app;
this.parent = parent || null;
diff --git a/src/component/props_validation.ts b/src/component/props_validation.ts
index 015d0345..0e7b5594 100644
--- a/src/component/props_validation.ts
+++ b/src/component/props_validation.ts
@@ -1,16 +1,16 @@
-import { Component } from "./component";
+import { ComponentConstructor } from "./component";
/**
* Apply default props (only top level).
*
* Note that this method does modify in place the props
*/
-export function applyDefaultProps(props: { [key: string]: any }, ComponentClass: typeof Component) {
- const defaultProps = (ComponentClass as any).defaultProps;
+export function applyDefaultProps (props: P, ComponentClass: ComponentConstructor ) {
+ const defaultProps = ComponentClass.defaultProps;
if (defaultProps) {
for (let propName in defaultProps) {
- if (props![propName] === undefined) {
- props![propName] = defaultProps[propName];
+ if ((props as any)[propName] === undefined) {
+ (props as any)[propName] = defaultProps[propName];
}
}
}
@@ -34,10 +34,11 @@ function getPropDescription(staticProps: any) {
* visit recursively the props and all the children to check if they are valid.
* This is why it is only done in 'dev' mode.
*/
-export const validateProps = function (name: string | typeof Component, props: any, parent?: any) {
- const ComponentClass = (
- typeof name !== "string" ? name : parent.constructor.components[name]
- ) as typeof Component;
+export function validateProps (name: string | ComponentConstructor , props: P, parent?: any) {
+ const ComponentClass =
+ typeof name !== "string"
+ ? name
+ : (parent.constructor.components[name] as ComponentConstructor | undefined);
if (!ComponentClass) {
// this is an error, wrong component. We silently return here instead so the
@@ -53,7 +54,7 @@ export const validateProps = function (name: string | typeof Component, props: a
if (propName === "*") {
continue;
}
- if (props[propName] === undefined) {
+ if ((props as any)[propName] === undefined) {
if (propsDef[propName] && !propsDef[propName].optional) {
throw new Error(`Missing props '${propName}' (component '${ComponentClass.name}')`);
} else {
@@ -62,7 +63,7 @@ export const validateProps = function (name: string | typeof Component, props: a
}
let isValid;
try {
- isValid = isValidProp(props[propName], propsDef[propName]);
+ isValid = isValidProp((props as any)[propName], propsDef[propName]);
} catch (e) {
(e as Error).message = `Invalid prop '${propName}' in component ${ComponentClass.name} (${
(e as Error).message
@@ -80,7 +81,7 @@ export const validateProps = function (name: string | typeof Component, props: a
}
}
}
-};
+}
/**
* Check if an invidual prop value matches its (static) prop definition