<p dir="auto"><strong>TypeScript Version:</strong><br>
1.8.7</p>
<p dir="auto"><strong>Code</strong></p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="interface Test {
    field: {[key: string]: string};
}

var test: Test;
var foo = {qwerty: 'qwerty'};

test = {
    field: foo
};"><pre class="notranslate"><span class="pl-k">interface</span> <span class="pl-smi">Test</span> <span class="pl-kos">{</span>
    <span class="pl-c1">field</span>: <span class="pl-kos">{</span><span class="pl-kos">[</span><span class="pl-s1">key</span>: <span class="pl-smi">string</span><span class="pl-kos">]</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-k">var</span> <span class="pl-s1">test</span>: <span class="pl-smi">Test</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-s1">foo</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-c1">qwerty</span>: <span class="pl-s">'qwerty'</span><span class="pl-kos">}</span><span class="pl-kos">;</span>

<span class="pl-s1">test</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
    <span class="pl-c1">field</span>: <span class="pl-s1">foo</span>
<span class="pl-kos">}</span><span class="pl-kos">;</span></pre></div>
<p dir="auto"><strong>Expected behavior:</strong><br>
I don't see any errors.</p>
<p dir="auto"><strong>Actual behavior:</strong><br>
I get the following error:</p>
<blockquote>
<p dir="auto">app\app.ts(46,1): error TS2322: Type '{ field: { qwerty: string; }; }' is not assignable to type 'Test'.<br>
Types of property 'field' are incompatible.<br>
Type '{ qwerty: string; }' is not assignable to type '{ [key: string]: string; }'.<br>
Index signature is missing in type '{ qwerty: string; }'.</p>
</blockquote>
<p dir="auto">If I modify my code to this then I don't get an error</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="interface Test {
    field: {[key: string]: string};
}

var test: Test;

test = {
    field: {qwerty: 'qwerty'}
};"><pre class="notranslate"><code class="notranslate">interface Test {
    field: {[key: string]: string};
}

var test: Test;

test = {
    field: {qwerty: 'qwerty'}
};
</code></pre></div>
<p dir="auto">Various libraries I use want to see dictionary "loops" that take some number of key/value pairs and operate on them. E.g.:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="async.auto&lt;any&gt;({
   'foo': (cb) =&gt; getFoo(cb),
   'bar': ['foo', (cb, results) =&gt; getBar(results.foo)]
}, (err, results) =&gt; { ... });"><pre class="notranslate"><code class="notranslate">async.auto&lt;any&gt;({
   'foo': (cb) =&gt; getFoo(cb),
   'bar': ['foo', (cb, results) =&gt; getBar(results.foo)]
}, (err, results) =&gt; { ... });
</code></pre></div>
<p dir="auto">The typings file for async likes to <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/async/async.d.ts#L6">define helper dictionary</a> types like this:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="interface Dictionary&lt;T&gt; { [key: string]: T; }"><pre class="notranslate"><code class="notranslate">interface Dictionary&lt;T&gt; { [key: string]: T; }
</code></pre></div>
<p dir="auto">Periodically, I need to create these key/value pairs conditionally and on the fly but the compiler yells at me if I try to send it in without explicitly typing my temporary object:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="var block = {
    'foo': (cb) =&gt; getFoo(cb),
    'bar': ['foo', (cb, results) =&gt; getBar(results.foo)
}

if (flag) {
    block.foo = getOtherFoo(cb);
}

async.auto&lt;any&gt;(block, (err, results) =&gt; { ... });"><pre class="notranslate"><code class="notranslate">var block = {
    'foo': (cb) =&gt; getFoo(cb),
    'bar': ['foo', (cb, results) =&gt; getBar(results.foo)
}

if (flag) {
    block.foo = getOtherFoo(cb);
}

async.auto&lt;any&gt;(block, (err, results) =&gt; { ... });
</code></pre></div>
<p dir="auto"><code class="notranslate">block</code> now technically satisfies the <code class="notranslate">{ [key: string]: T; }</code> because it is an object with two keys, both strings. TypeScript will still yell at me for it, though, unless I explicit add a similar dictionary type to <code class="notranslate">block</code>. I, therefore, find myself putting this dictionary type all over the place just to satisfy what seems to be an arbitrary distinction between what is or is not a <code class="notranslate">key:string</code>.</p>
<p dir="auto">This comes up enough that I find the type bloat irritating and it also makes it a requirement to <em>only</em> access <code class="notranslate">block.foo</code> as <code class="notranslate">block['foo']</code>.</p>