Improve Typescript definition for MithrilRoutes
The previous definition of MithrilRoutes was generic over <T extends
MithrilController>, with the MithrilRoutes containing a collection of
MithrilComponent<T>.
However, this presents problems with TypeScript's type inference in many common
situations. For example, consider this usage of m.route():
```
m.route(document.body, "/a", {
"/a": ComponentA,
"/b": ComponentB,
})
```
Both `ComponentA` and `ComponentB` implement `MithrilComponent<T extends
MithrilController>`, with each component having a different concrete controller
type (`ControllerA` and `ControllerB`).
However, unless ControllerA's type is a subset of ControllerB's type (or
vice-versa), TypeScript will be unable to infer the type of the MitrilRoutes<T>
returned by m.route(). To get this to compile, a third type which *is* a
subset of both ControllerA and ControllerB would need to be explicity provided:
```
// Both ControllerA and ControllerB implement MithrilController
m.route<MithrilController>(document.body, "/a", {
"/a": ComponentA,
"/b": ComponentB,
})
```
This commit makes MithrilRoute non-generic, and instead of containing
MithrilComponent<T extends MithrilRoute>, it contains
MithrilComponent<MithrilController>, which will match all valid
MithrilComponents.
The motivation for this change is twofold:
1. In the case where m.route() does not compile due to type-inference failure,
the resulting syntax error from Typescript is very unhelpful because m.route()
has a number of overloads. Leaving this as is will result in confusion for
downstream users.
2. An assumption that vanishingly little utility is provided by defining
`MithrilRoutes<T extends MithrilController>` over a type more specific than
MithrilController. At most, it could be used to assert that all of your routed
Components meet a more specialized interface, but that same type check could be
accomplished without having to augment MithrilRoutes with that information.
This commit is contained in:
parent
6f15a9b148
commit
26f68744b5
1 changed files with 5 additions and 5 deletions
10
mithril.d.ts
vendored
10
mithril.d.ts
vendored
|
|
@ -431,10 +431,10 @@ declare module _mithril {
|
|||
* @param defaultRoute The route to start with.
|
||||
* @param routes A key-value mapping of pathname to controller.
|
||||
*/
|
||||
<T extends MithrilController>(
|
||||
(
|
||||
rootElement: Element,
|
||||
defaultRoute: string,
|
||||
routes: MithrilRoutes<T>
|
||||
routes: MithrilRoutes
|
||||
): void;
|
||||
|
||||
/**
|
||||
|
|
@ -447,7 +447,7 @@ declare module _mithril {
|
|||
* m("a[href='/dashboard/alicesmith']", {config: m.route});
|
||||
* ```
|
||||
*/
|
||||
<T extends MithrilController>(
|
||||
(
|
||||
element: Element,
|
||||
isInitialized: boolean,
|
||||
context?: MithrilContext,
|
||||
|
|
@ -876,12 +876,12 @@ declare module _mithril {
|
|||
/**
|
||||
* This represents a key-value mapping linking routes to components.
|
||||
*/
|
||||
interface MithrilRoutes<T extends MithrilController> {
|
||||
interface MithrilRoutes {
|
||||
/**
|
||||
* The key represents the route. The value represents the corresponding
|
||||
* component.
|
||||
*/
|
||||
[key: string]: MithrilComponent<T>;
|
||||
[key: string]: MithrilComponent<MithrilController>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue