Typescript: Make MithrilVirtualElement non-generic
`MithrilVirtualElement` was recently converted to be generic over `<T extends MithrilController>`. The element's `children` may then contain other `MithrilVirtualElement<T>` or `MithrilComponent<T>` elements. Unfortunately, in common usage of 'm()' this can cause problems with Mithril's type inference system. If a type is not explicitly provided to `m()`, the "T" of the returned MithrilVirtualElement<T> will be inferred from its children. The candidates for T will be the concrete types of the child MithrilComponent<T>; however, if no candidate type is a subset of *every* candidate type, then TypeScript will be unable to infer a valid type, and the call to `m()` will not compile. To improve this behavior, this commit makes MithrilVirtualElement non-generic; it's child collection can now contain MithrilComponent<MithrilController>, which matches all valid MithrilComponent. This the same underlying issue as the previous commit, which made MithrilRoutes non-generic. The motivation for fixing this is threefold: 1. Because `m()` has so many overloads, in the case where a call to `m()` will not compile due to the above issue, the syntax error provided by TypeScript is not helpful. 2. In many cases, users will be calling `m<MithrilController>()` in their code simply to get it to compile, which provides no additional utility over a non-generic type and adds significant boilerplate. 3. Explicitly specifying subtypes to `m()` calls provides little utility; at best, it can check that contained components implement some common interface. However, type assertions like that can be provided in other places without having to attach the information to the MithrilVirtualElement.
This commit is contained in:
parent
26f68744b5
commit
da6d525a11
1 changed files with 18 additions and 18 deletions
36
mithril.d.ts
vendored
36
mithril.d.ts
vendored
|
|
@ -20,13 +20,13 @@ declare module _mithril {
|
|||
* @see m.mount
|
||||
* @see m.component
|
||||
*/
|
||||
<T extends MithrilController>(
|
||||
(
|
||||
selector: string,
|
||||
attributes: MithrilAttributes,
|
||||
...children: Array<string |
|
||||
MithrilVirtualElement<T> |
|
||||
MithrilComponent<T>>
|
||||
): MithrilVirtualElement<T>;
|
||||
MithrilVirtualElement |
|
||||
MithrilComponent<MithrilController>>
|
||||
): MithrilVirtualElement;
|
||||
|
||||
/**
|
||||
* Creates a virtual element for use with m.render, m.mount, etc.
|
||||
|
|
@ -40,12 +40,12 @@ declare module _mithril {
|
|||
* @see m.mount
|
||||
* @see m.component
|
||||
*/
|
||||
<T extends MithrilController>(
|
||||
(
|
||||
selector: string,
|
||||
...children: Array<string |
|
||||
MithrilVirtualElement<T> |
|
||||
MithrilComponent<T>>
|
||||
): MithrilVirtualElement<T>;
|
||||
MithrilVirtualElement |
|
||||
MithrilComponent<MithrilController>>
|
||||
): MithrilVirtualElement;
|
||||
|
||||
/**
|
||||
* Initializes a component for use with m.render, m.mount, etc.
|
||||
|
|
@ -364,9 +364,9 @@ declare module _mithril {
|
|||
* @param forceRecreation If true, overwrite the entire tree without
|
||||
* diffing against it.
|
||||
*/
|
||||
render<T extends MithrilController>(
|
||||
render(
|
||||
rootElement: Element,
|
||||
children: MithrilVirtualElement<T>|MithrilVirtualElement<T>[],
|
||||
children: MithrilVirtualElement|MithrilVirtualElement[],
|
||||
forceRecreation?: boolean
|
||||
): void;
|
||||
|
||||
|
|
@ -451,7 +451,7 @@ declare module _mithril {
|
|||
element: Element,
|
||||
isInitialized: boolean,
|
||||
context?: MithrilContext,
|
||||
vdom?: MithrilVirtualElement<T>
|
||||
vdom?: MithrilVirtualElement
|
||||
): void;
|
||||
|
||||
/**
|
||||
|
|
@ -615,7 +615,7 @@ declare module _mithril {
|
|||
*
|
||||
* @see m
|
||||
*/
|
||||
interface MithrilVirtualElement<T extends MithrilController> {
|
||||
interface MithrilVirtualElement {
|
||||
/**
|
||||
* A key to optionally associate with this element.
|
||||
*/
|
||||
|
|
@ -634,7 +634,7 @@ declare module _mithril {
|
|||
/**
|
||||
* The children of this element.
|
||||
*/
|
||||
children?: Array<string|MithrilVirtualElement<T>|MithrilComponent<T>>;
|
||||
children?: Array<string|MithrilVirtualElement|MithrilComponent<MithrilController>>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -686,11 +686,11 @@ declare module _mithril {
|
|||
* @param context The associated context for this element.
|
||||
* @param vdom The associated virtual element.
|
||||
*/
|
||||
<T extends MithrilController>(
|
||||
(
|
||||
element: Element,
|
||||
isInitialized: boolean,
|
||||
context: MithrilContext,
|
||||
vdom: MithrilVirtualElement<T>
|
||||
vdom: MithrilVirtualElement
|
||||
): void;
|
||||
}
|
||||
|
||||
|
|
@ -758,7 +758,7 @@ declare module _mithril {
|
|||
/**
|
||||
* Creates a view out of virtual elements.
|
||||
*/
|
||||
(ctrl: T): MithrilVirtualElement<T>;
|
||||
(ctrl: T): MithrilVirtualElement;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -781,7 +781,7 @@ declare module _mithril {
|
|||
*
|
||||
* @see m.component
|
||||
*/
|
||||
view(ctrl: T): MithrilVirtualElement<T>;
|
||||
view(ctrl: T): MithrilVirtualElement;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -805,7 +805,7 @@ declare module _mithril {
|
|||
*
|
||||
* @see m.component
|
||||
*/
|
||||
view(ctrl: TController, arg1: T1, arg2: T2, arg3: T3, arg4: T4, ...args:any[]): MithrilVirtualElement<TController>;
|
||||
view(ctrl: TController, arg1: T1, arg2: T2, arg3: T3, arg4: T4, ...args:any[]): MithrilVirtualElement;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue