<p dir="auto">It's currently possible to do this:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="  method&lt;A extends Array&lt;number&gt;&gt;(one):number;
  method&lt;A extends Array&lt;string&gt;&gt;(two):string;"><pre class="notranslate">  <span class="pl-s1">method</span><span class="pl-c1">&lt;</span><span class="pl-smi">A</span> <span class="pl-k">extends</span> <span class="pl-smi">Array</span><span class="pl-kos">&lt;</span><span class="pl-smi">number</span><span class="pl-kos">&gt;</span><span class="pl-c1">&gt;</span><span class="pl-kos">(</span><span class="pl-smi">one</span><span class="pl-kos">)</span>:<span class="pl-smi">number</span><span class="pl-kos">;</span>
  <span class="pl-s1">method</span><span class="pl-c1">&lt;</span><span class="pl-smi">A</span> <span class="pl-k">extends</span> <span class="pl-smi">Array</span><span class="pl-kos">&lt;</span><span class="pl-smi">string</span><span class="pl-kos">&gt;</span><span class="pl-c1">&gt;</span><span class="pl-kos">(</span><span class="pl-smi">two</span><span class="pl-kos">)</span>:<span class="pl-smi">string</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">But not possible to do this:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="interface Example&lt;T extends Array&lt;number&gt;&gt; {
  method(one):number;
}
interface Example&lt;T extends Array&lt;string&gt;&gt; {
  method(two):string;
}"><pre class="notranslate"><span class="pl-k">interface</span> <span class="pl-smi">Example</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span> <span class="pl-k">extends</span> <span class="pl-smi">Array</span><span class="pl-kos">&lt;</span><span class="pl-smi">number</span><span class="pl-kos">&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-c1">method</span><span class="pl-kos">(</span><span class="pl-s1">one</span><span class="pl-kos">)</span>:<span class="pl-smi">number</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>
<span class="pl-k">interface</span> <span class="pl-smi">Example</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span> <span class="pl-k">extends</span> <span class="pl-smi">Array</span><span class="pl-kos">&lt;</span><span class="pl-smi">string</span><span class="pl-kos">&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-c1">method</span><span class="pl-kos">(</span><span class="pl-s1">two</span><span class="pl-kos">)</span>:<span class="pl-smi">string</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">This means we cannot have different typings depending on the generic type constraint of the interface.<br>
I've even tried a hack like this:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="interface Example&lt;T extends Array&lt;any&gt;&gt; {
  method&lt;A extends T &amp; Array&lt;number&gt;&gt;(one):number;
  method&lt;A extends T &amp; Array&lt;string&gt;&gt;(two):string;
}"><pre class="notranslate"><span class="pl-k">interface</span> <span class="pl-smi">Example</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span> <span class="pl-k">extends</span> <span class="pl-smi">Array</span><span class="pl-kos">&lt;</span><span class="pl-smi">any</span><span class="pl-kos">&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-c1">method</span><span class="pl-c1">&lt;</span><span class="pl-smi">A</span> <span class="pl-k">extends</span> <span class="pl-smi">T</span> <span class="pl-c1">&amp;</span> <span class="pl-smi">Array</span><span class="pl-kos">&lt;</span><span class="pl-smi">number</span><span class="pl-kos">&gt;</span><span class="pl-c1">&gt;</span><span class="pl-kos">(</span><span class="pl-s1">one</span><span class="pl-kos">)</span>:<span class="pl-smi">number</span><span class="pl-kos">;</span>
  <span class="pl-c1">method</span><span class="pl-c1">&lt;</span><span class="pl-smi">A</span> <span class="pl-k">extends</span> <span class="pl-smi">T</span> <span class="pl-c1">&amp;</span> <span class="pl-smi">Array</span><span class="pl-kos">&lt;</span><span class="pl-smi">string</span><span class="pl-kos">&gt;</span><span class="pl-c1">&gt;</span><span class="pl-kos">(</span><span class="pl-s1">two</span><span class="pl-kos">)</span>:<span class="pl-smi">string</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">I was hoping that TS will infer the type of the T array from the intersect, unfortunately that does not happen (it offers both methods, regardless of whether Example is an instance of <code class="notranslate">Example&lt;Array&lt;number&gt;&gt;</code> or of <code class="notranslate">Example&lt;Array&lt;string&gt;&gt;</code>).</p>
<p dir="auto">Among other uses, this feature would be useful for a variety of database libraries that return internal types that can have their own operations done on them. For example, when I <code class="notranslate">map</code> an <code class="notranslate">DbArray&lt;DbNumber&gt;</code>, I should get a different set of methods than when operating on <code class="notranslate">DbArray&lt;DbString&gt;</code>.</p>
<p dir="auto">The current workaround is to ask the user to explicitly declare both - the outer and the inner type, e.g.:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="interface Example&lt;TOuter, TInner&gt; {
  map&lt;TOut&gt;((item: TInner) =&gt; TOut): TOut;
  // ...TOuter used in another method
}"><pre class="notranslate"><span class="pl-k">interface</span> <span class="pl-smi">Example</span><span class="pl-c1">&lt;</span><span class="pl-smi">TOuter</span><span class="pl-kos">,</span> <span class="pl-smi">TInner</span><span class="pl-c1">&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-c1">map</span><span class="pl-c1">&lt;</span><span class="pl-smi">TOut</span><span class="pl-c1">&gt;</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-s1">item</span>: <span class="pl-smi">TInner</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">TOut</span><span class="pl-kos">)</span>: <span class="pl-smi">TOut</span><span class="pl-kos">;</span>
  <span class="pl-c">// ...TOuter used in another method</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">However, this <code class="notranslate">TInner</code> is redundant (it's already inside of TOuter) and sometimes not relevant at all.<br>
With more complex types this can cause the introduction of even more generic types, that grow like cancer in the declarations (<code class="notranslate">interface Example&lt;A, B, C, D, ...&gt;</code>) - the more possibilities there are, the more explicit declarations need to be done at the interface level. This has been an obstacle to creating proper type definitions for RethinkDB <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="85172338" data-permission-text="Title is private" data-url="https://github.com/DefinitelyTyped/DefinitelyTyped/issues/4551" data-hovercard-type="issue" data-hovercard-url="/DefinitelyTyped/DefinitelyTyped/issues/4551/hovercard" href="https://github.com/DefinitelyTyped/DefinitelyTyped/issues/4551">DefinitelyTyped/DefinitelyTyped#4551</a>.</p>
<p dir="auto">Last example: an interface <code class="notranslate">DbValue</code> can be a generic of any primitive type in the database: an <code class="notranslate">array</code>, a <code class="notranslate">string</code> or a <code class="notranslate">number</code>.<br>
For an instance of an <code class="notranslate">array</code>, you'd need to pass in <code class="notranslate">DbValue&lt;Array&lt;number&gt;, number&gt;</code>, yet for an instance of string, the second parameter is irrelevant: <code class="notranslate">DbValue&lt;string, void&gt;</code>.</p>
<p dir="auto">What we'd need is to be able to constrain not only by method's own generics, but by the containing interfaces generics, for method signatures themselves, something like:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="interface Example&lt;T&gt; {
  // here the constraint is not of the method, but of the type
  method(one):number where T extends Array&lt;number&gt;;
  method(two):string where T extends Array&lt;string&gt;;
}"><pre class="notranslate"><span class="pl-k">interface</span> <span class="pl-smi">Example</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span><span class="pl-c1">&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-c">// here the constraint is not of the method, but of the type</span>
  <span class="pl-c1">method</span><span class="pl-kos">(</span><span class="pl-s1">one</span><span class="pl-kos">)</span>:<span class="pl-smi">number</span> <span class="pl-s1">where</span> <span class="pl-smi">T</span> <span class="pl-k">extends</span> <span class="pl-smi">Array</span><span class="pl-kos">&lt;</span><span class="pl-smi">number</span><span class="pl-kos">&gt;</span><span class="pl-kos">;</span>
  <span class="pl-c1">method</span><span class="pl-kos">(</span><span class="pl-s1">two</span><span class="pl-kos">)</span>:<span class="pl-smi">string</span> <span class="pl-s1">where</span> <span class="pl-smi">T</span> <span class="pl-k">extends</span> <span class="pl-smi">Array</span><span class="pl-kos">&lt;</span><span class="pl-smi">string</span><span class="pl-kos">&gt;</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<blockquote>
<p dir="auto">This is a suggestion for spec change.</p>
</blockquote>
<h3 dir="auto">Problem</h3>
<p dir="auto">Sometimes type's members could only be applicable with some restrictions of enclosing type parameter (generic type constraints).</p>
<p dir="auto">For instance, this is use case of RxJS:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var xs: Observable&lt;Observable&lt;string&gt;&gt;;
xs.mergeAll();  // mergeAll is applicable here

var ys: Observable&lt;string&gt;;
ys.mergeAll();  // mergeAll is NOT applicable here"><pre class="notranslate"><span class="pl-k">var</span> <span class="pl-s1">xs</span>: <span class="pl-smi">Observable</span><span class="pl-kos">&lt;</span><span class="pl-smi">Observable</span><span class="pl-kos">&lt;</span><span class="pl-smi">string</span><span class="pl-kos">&gt;</span><span class="pl-kos">&gt;</span><span class="pl-kos">;</span>
<span class="pl-s1">xs</span><span class="pl-kos">.</span><span class="pl-en">mergeAll</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>  <span class="pl-c">// mergeAll is applicable here</span>

<span class="pl-k">var</span> <span class="pl-s1">ys</span>: <span class="pl-smi">Observable</span><span class="pl-kos">&lt;</span><span class="pl-smi">string</span><span class="pl-kos">&gt;</span><span class="pl-kos">;</span>
<span class="pl-s1">ys</span><span class="pl-kos">.</span><span class="pl-en">mergeAll</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>  <span class="pl-c">// mergeAll is NOT applicable here</span></pre></div>
<p dir="auto">Original Rx.NET <a href="http://msdn.microsoft.com/en-us/library/hh229740%28v=vs.103%29.aspx" rel="nofollow">Merge</a> method implemented as C# extension method on type <code class="notranslate">IObservable&lt;IObservable&lt;T&gt;&gt;</code>. In RxJS it's implemented as an instance method.</p>
<p dir="auto">Current RxJS typescript definition just use <a href="https://github.com/Reactive-Extensions/RxJS/blob/master/ts/rx-lite.d.ts#L258">unsafe trick</a>:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="export interface Observable&lt;T&gt; {
  ...
  mergeAll(): T;
  ...
}"><pre class="notranslate"><span class="pl-k">export</span> <span class="pl-k">interface</span> <span class="pl-smi">Observable</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span><span class="pl-c1">&gt;</span> <span class="pl-kos">{</span>
  ...
  <span class="pl-c1">mergeAll</span><span class="pl-kos">(</span><span class="pl-kos">)</span>: <span class="pl-smi">T</span><span class="pl-kos">;</span>
  ...
<span class="pl-kos">}</span></pre></div>
<p dir="auto">But it can be still unsafely called for as instance of any <code class="notranslate">Observable&lt;T&gt;</code>.</p>
<h3 dir="auto">Possible solutions</h3>
<h4 dir="auto">Extension methods</h4>
<p dir="auto">Something like C# extension methods. But don't think it's useful in such cases.</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="declare extensions {
  mergeAll&lt;T&gt;(this Observable&lt;Observable&lt;T&gt;&gt; source): Observable&lt;T&gt;;
}"><pre class="notranslate"><span class="pl-k">declare</span> <span class="pl-s1">extensions</span> <span class="pl-kos">{</span>
  <span class="pl-c1">mergeAll</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span><span class="pl-c1">&gt;</span><span class="pl-kos">(</span><span class="pl-smi">this</span> <span class="pl-smi">Observable</span><span class="pl-c1">&lt;</span><span class="pl-smi">Observable</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span><span class="pl-c1">&gt;&gt;</span> <span class="pl-s1">source</span><span class="pl-kos">)</span>: <span class="pl-smi">Observable</span><span class="pl-kos">&lt;</span><span class="pl-smi">T</span><span class="pl-kos">&gt;</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">BTW, extensions method could be other cool feature, which change call method (from instance-like to static-like).</p>
<h4 dir="auto">Multiple interface definitions with different constraints</h4>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="interface A&lt;T&gt; { x(): void; }
interface A&lt;T extends B&gt; { y(): void; }
var a: A&lt;number&gt;;
var b: A&lt;B&gt;;

a.x(); b.x(); // ok
b.y(); // ok
a.y(); // error"><pre class="notranslate"><span class="pl-k">interface</span> <span class="pl-smi">A</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span><span class="pl-c1">&gt;</span> <span class="pl-kos">{</span> <span class="pl-c1">x</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-k">interface</span> <span class="pl-smi">A</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span> <span class="pl-k">extends</span> <span class="pl-smi">B</span><span class="pl-c1">&gt;</span> <span class="pl-kos">{</span> <span class="pl-c1">y</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-k">var</span> <span class="pl-s1">a</span>: <span class="pl-smi">A</span><span class="pl-kos">&lt;</span><span class="pl-smi">number</span><span class="pl-kos">&gt;</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-s1">b</span>: <span class="pl-smi">A</span><span class="pl-kos">&lt;</span><span class="pl-smi">B</span><span class="pl-kos">&gt;</span><span class="pl-kos">;</span>

<span class="pl-s1">a</span><span class="pl-kos">.</span><span class="pl-en">x</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-s1">b</span><span class="pl-kos">.</span><span class="pl-en">x</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// ok</span>
<span class="pl-s1">b</span><span class="pl-kos">.</span><span class="pl-en">y</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// ok</span>
<span class="pl-s1">a</span><span class="pl-kos">.</span><span class="pl-en">y</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// error</span></pre></div>
<h4 dir="auto">Member-level constraints with reference to enclosing type arguments</h4>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="interface A&lt;T&gt; {
  x(): void;
  y&lt;T extends B&gt;(): void; // only applicable if T extends B
  z&lt;T extends B&gt;: number; // for any property
  // alternative syntax options:
  &lt;T extends B&gt;z: number;  // 1

  z: number where T extends B;  // 2
  y(): void where T extends B;
}"><pre class="notranslate"><span class="pl-k">interface</span> <span class="pl-smi">A</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span><span class="pl-c1">&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-c1">x</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-c1">y</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span> <span class="pl-k">extends</span> <span class="pl-smi">B</span><span class="pl-c1">&gt;</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-c">// only applicable if T extends B</span>
  <span class="pl-c1">z</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span> <span class="pl-k">extends</span> <span class="pl-smi">B</span><span class="pl-c1">&gt;</span>: <span class="pl-smi">number</span><span class="pl-kos">;</span> <span class="pl-c">// for any property</span>
  <span class="pl-c">// alternative syntax options:</span>
  <span class="pl-c1">&lt;</span><span class="pl-smi">T</span> <span class="pl-k">extends</span> <span class="pl-smi">B</span><span class="pl-c1">&gt;</span><span class="pl-c1">z</span>: <span class="pl-smi">number</span><span class="pl-kos">;</span>  <span class="pl-c">// 1</span>

  <span class="pl-c1">z</span>: <span class="pl-smi">number</span> <span class="pl-s1">where</span> <span class="pl-smi">T</span> <span class="pl-k">extends</span> <span class="pl-smi">B</span><span class="pl-kos">;</span>  <span class="pl-c">// 2</span>
  <span class="pl-c1">y</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-s1">where</span> <span class="pl-smi">T</span> <span class="pl-k">extends</span> <span class="pl-smi">B</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">I'll suggest this option. Moreover the previous solution options is special case of this one (incompatible constraints are merged on member level).</p>