[IMP] types: do not make Env an indexed type

Before this commit, Env was an indexed type, this means that one could
write env.anything, and it would accept it as a valid type. This is
actually quite dangerous, because we lose the typing advantages for all
keys that are properly defined.

For example, if a component is defined as:

class MyComponent extends Component<Props> {
 ...
}

Then Typescript will let it use anything from the environment, even if
it is wrong.  So, most properly typed Typescript applications should use
instead a sub environment:

interface MyAppEnv extends Env {
  someKey: someValue
}

Then, the component should be defined this way:

class MyComponent extends Component<Props, MyAppEnv> {
 ...
}

Before this commit, any typos in the environment accesses would not be
noticed by typescript.
This commit is contained in:
Géry Debongnie
2020-04-17 11:30:25 +02:00
committed by aab-odoo
parent 94c8bce810
commit 142b69823f
6 changed files with 26 additions and 11 deletions
+7 -3
View File
@@ -24,6 +24,10 @@ import { onWillUpdateProps } from "./hooks";
// Store Definition
//------------------------------------------------------------------------------
export interface EnvWithStore extends Env {
store: Store;
}
export type Action = ({ state, dispatch, env, getters }, ...payload: any) => any;
export type Getter = ({ state: any, getters }, payload?) => any;
@@ -83,7 +87,7 @@ interface SelectorOptions {
const isStrictEqual = (a, b) => a === b;
export function useStore(selector, options: SelectorOptions = {}): any {
const component: Component = Component.current!;
const component = Component.current as Component<any, EnvWithStore>;
const componentId = component.__owl__.id;
const store = options.store || (component.env.store as Store);
if (!(store instanceof Store)) {
@@ -149,11 +153,11 @@ export function useStore(selector, options: SelectorOptions = {}): any {
}
export function useDispatch(store?: Store): Store["dispatch"] {
store = store || (Component.current!.env.store as Store);
store = store || (Component.current!.env as EnvWithStore).store;
return store.dispatch.bind(store);
}
export function useGetters(store?: Store): Store["getters"] {
store = store || (Component.current!.env.store as Store);
store = store || (Component.current!.env as EnvWithStore).store;
return store.getters;
}