<p dir="auto">I think the following should compile with no error:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="declare module Backbone {
    interface RoutesHash {
        [routePattern: string]: string | {(...urlParts: string[]): void};
    }
    class Events { }
    class Router extends Events {
        routes: RoutesHash;
    }
}

declare module Marionette {
    class AppRouter extends Backbone.Router {
    }
}

module Backbone.Tests {
    // Error, routes is not contextually typed
    class MyRouter extends Backbone.Router {
        routes = {
            &quot;some/route&quot;: &quot;someMethod&quot;,
            &quot;some/otherRoute&quot;: () =&gt; {}
        };
    }
}

module Marionette.Tests {
    // Error, routes is not contextually typed
    class MyRouter extends Marionette.AppRouter {
        routes = {
            &quot;some/route&quot;: &quot;someMethod&quot;,
            &quot;some/otherRoute&quot;: () =&gt; {}
        };
    }
}"><pre class="notranslate"><span class="pl-k">declare</span> module <span class="pl-smi">Backbone</span> <span class="pl-kos">{</span>
    <span class="pl-k">interface</span> <span class="pl-smi">RoutesHash</span> <span class="pl-kos">{</span>
        <span class="pl-kos">[</span><span class="pl-s1">routePattern</span>: <span class="pl-smi">string</span><span class="pl-kos">]</span>: <span class="pl-smi">string</span> <span class="pl-c1">|</span> <span class="pl-kos">{</span><span class="pl-kos">(</span>...<span class="pl-s1">urlParts</span>: <span class="pl-smi">string</span><span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">)</span>: <span class="pl-smi"><span class="pl-k">void</span></span><span class="pl-kos">}</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>
    <span class="pl-k">class</span> <span class="pl-smi">Events</span> <span class="pl-kos">{</span> <span class="pl-kos">}</span>
    <span class="pl-k">class</span> <span class="pl-smi">Router</span> <span class="pl-k">extends</span> <span class="pl-smi">Events</span> <span class="pl-kos">{</span>
        <span class="pl-c1">routes</span>: <span class="pl-smi">RoutesHash</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

<span class="pl-k">declare</span> module <span class="pl-smi">Marionette</span> <span class="pl-kos">{</span>
    <span class="pl-k">class</span> <span class="pl-smi">AppRouter</span> <span class="pl-k">extends</span> <span class="pl-smi">Backbone</span><span class="pl-kos">.</span><span class="pl-c1">Router</span> <span class="pl-kos">{</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

module <span class="pl-smi">Backbone</span><span class="pl-kos">.</span><span class="pl-smi">Tests</span> <span class="pl-kos">{</span>
    <span class="pl-c">// Error, routes is not contextually typed</span>
    <span class="pl-k">class</span> <span class="pl-smi">MyRouter</span> <span class="pl-k">extends</span> <span class="pl-smi">Backbone</span><span class="pl-kos">.</span><span class="pl-c1">Router</span> <span class="pl-kos">{</span>
        <span class="pl-c1">routes</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
            <span class="pl-s">"some/route"</span>: <span class="pl-s">"someMethod"</span><span class="pl-kos">,</span>
            <span class="pl-s">"some/otherRoute"</span>: <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>
        <span class="pl-kos">}</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

module <span class="pl-smi">Marionette</span><span class="pl-kos">.</span><span class="pl-smi">Tests</span> <span class="pl-kos">{</span>
    <span class="pl-c">// Error, routes is not contextually typed</span>
    <span class="pl-k">class</span> <span class="pl-smi">MyRouter</span> <span class="pl-k">extends</span> <span class="pl-smi">Marionette</span><span class="pl-kos">.</span><span class="pl-c1">AppRouter</span> <span class="pl-kos">{</span>
        <span class="pl-c1">routes</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
            <span class="pl-s">"some/route"</span>: <span class="pl-s">"someMethod"</span><span class="pl-kos">,</span>
            <span class="pl-s">"some/otherRoute"</span>: <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>
        <span class="pl-kos">}</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">When a property has exactly one type from an <code class="notranslate">extends</code> or <code class="notranslate">implements</code> clause, we should contextually type that property's initializer by the type from the clause. For example:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="interface ThingListener {
    handleEvent: (x: MouseEvent) =&gt; void;
}

class Foo implements ThingListener {
    handleEvent = x =&gt; {
        // No error, but this code is incorrect
        console.log(x.timestamp);
    }
}"><pre class="notranslate"><span class="pl-k">interface</span> <span class="pl-smi">ThingListener</span> <span class="pl-kos">{</span>
    <span class="pl-c1">handleEvent</span>: <span class="pl-kos">(</span><span class="pl-s1">x</span>: <span class="pl-smi">MouseEvent</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi"><span class="pl-k">void</span></span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">class</span> <span class="pl-smi">Foo</span> <span class="pl-k">implements</span> <span class="pl-smi">ThingListener</span> <span class="pl-kos">{</span>
    <span class="pl-c1">handleEvent</span> <span class="pl-c1">=</span> <span class="pl-s1">x</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
        <span class="pl-c">// No error, but this code is incorrect</span>
        <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s1">x</span><span class="pl-kos">.</span><span class="pl-c1">timestamp</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">Ideally we could take this one step further when widening. The following behavior is also undesirable:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="interface HasLength {
    length: number
}

class Foo implements HasLength {
    // length: any, not really what we intended
    length = undefined;
}

var x = new Foo();
x.length = 'wat'; // should not be allowed"><pre class="notranslate"><span class="pl-k">interface</span> <span class="pl-smi">HasLength</span> <span class="pl-kos">{</span>
    <span class="pl-c1">length</span>: <span class="pl-smi">number</span>
<span class="pl-kos">}</span>

<span class="pl-k">class</span> <span class="pl-smi">Foo</span> <span class="pl-k">implements</span> <span class="pl-smi">HasLength</span> <span class="pl-kos">{</span>
    <span class="pl-c">// length: any, not really what we intended</span>
    <span class="pl-c1">length</span> <span class="pl-c1">=</span> <span class="pl-c1">undefined</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">var</span> <span class="pl-s1">x</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-smi">Foo</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-s1">x</span><span class="pl-kos">.</span><span class="pl-c1">length</span> <span class="pl-c1">=</span> <span class="pl-s">'wat'</span><span class="pl-kos">;</span> <span class="pl-c">// should not be allowed</span></pre></div>
<p dir="auto">e.g. <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="91669978" data-permission-text="Title is private" data-url="https://github.com/microsoft/TypeScript/issues/3666" data-hovercard-type="issue" data-hovercard-url="/microsoft/TypeScript/issues/3666/hovercard" href="https://github.com/microsoft/TypeScript/issues/3666">#3666</a></p>