From 26f68744b5d69d73ddb2fcc2d1d21ec25a427059 Mon Sep 17 00:00:00 2001 From: Matt Tracy Date: Tue, 29 Sep 2015 14:05:53 -0400 Subject: [PATCH] Improve Typescript definition for MithrilRoutes The previous definition of MithrilRoutes was generic over , with the MithrilRoutes containing a collection of MithrilComponent. 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`, 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 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(document.body, "/a", { "/a": ComponentA, "/b": ComponentB, }) ``` This commit makes MithrilRoute non-generic, and instead of containing MithrilComponent, it contains MithrilComponent, 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` 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. --- mithril.d.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mithril.d.ts b/mithril.d.ts index a5c24a6e..2952d92a 100644 --- a/mithril.d.ts +++ b/mithril.d.ts @@ -431,10 +431,10 @@ declare module _mithril { * @param defaultRoute The route to start with. * @param routes A key-value mapping of pathname to controller. */ - ( + ( rootElement: Element, defaultRoute: string, - routes: MithrilRoutes + routes: MithrilRoutes ): void; /** @@ -447,7 +447,7 @@ declare module _mithril { * m("a[href='/dashboard/alicesmith']", {config: m.route}); * ``` */ - ( + ( 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 { + interface MithrilRoutes { /** * The key represents the route. The value represents the corresponding * component. */ - [key: string]: MithrilComponent; + [key: string]: MithrilComponent; } /**