<p dir="auto">Currently TS tools can't autocomplete property names that are not identifiers. e.g.:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="interface Style {
    'font-family'?: string;
}"><pre class="notranslate"><span class="pl-s1">interface</span> <span class="pl-v">Style</span> <span class="pl-kos">{</span>
    <span class="pl-s">'font-family'</span>?<span class="pl-s1"></span>: <span class="pl-s1">string</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">There is no autocomplete for the following input:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="var style: Style = { 'fo // no autocomplete
style[ // no autocomplete
style. // no autocomplete"><pre class="notranslate"><code class="notranslate">var style: Style = { 'fo // no autocomplete
style[ // no autocomplete
style. // no autocomplete
</code></pre></div>
<p dir="auto">I think maybe TS can do better here: show a list of all properties, after user has selected one, quote it and use brackets if neccesary.</p>
<p dir="auto">Many JavaScript frameworks are heavily based on using string values to do many things, from getting and setting attributes via the property name in string form, to defining event handlers to handle browsing to particular URLs. TypeScript added specialized signatures in overloads as one means to help mitigate the pain associated with these types of APIs. Unfortunately for a number of patterns this is insufficient and not general enough. Rather than try to design a specific type system enhancement that could handle some or all of the many ways these frameworks use string literals we could try some simple tricks in Visual Studio to help out. Namely, when typing a string literal the editor should provide a completion list based on other string literals already used in your program. Some other tools already provide similar capabilities (ex Sublime Text).</p>
<p dir="auto">Consider something like this in a Backbone View class:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="class TodoView extends Backbone.View&lt;TodoModel&gt; {
    initialize() {
        this.listenTo(this.model, 'change', () =&gt; this.render());
        this.listenTo(this.model, 'todoDescriptionChanged', () =&gt; this.render());
        this.listenTo(this.model, 'destory', () =&gt; this.remove());
    }"><pre class="notranslate"><span class="pl-k">class</span> <span class="pl-smi">TodoView</span> <span class="pl-k">extends</span> <span class="pl-smi">Backbone</span><span class="pl-kos">.</span><span class="pl-c1">View</span><span class="pl-c1">&lt;</span><span class="pl-smi">TodoModel</span><span class="pl-c1">&gt;</span> <span class="pl-kos">{</span>
    <span class="pl-en">initialize</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
        <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-en">listenTo</span><span class="pl-kos">(</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">model</span><span class="pl-kos">,</span> <span class="pl-s">'change'</span><span class="pl-kos">,</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-en">render</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-en">listenTo</span><span class="pl-kos">(</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">model</span><span class="pl-kos">,</span> <span class="pl-s">'todoDescriptionChanged'</span><span class="pl-kos">,</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-en">render</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-en">listenTo</span><span class="pl-kos">(</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">model</span><span class="pl-kos">,</span> <span class="pl-s">'destory'</span><span class="pl-kos">,</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-en">remove</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">At another point I may attempt to manually trigger one of these events:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="    updateTodo() {
        var desc = this.$input.val().trim();
        var todo = this.model;
        if (desc) {
            todo.save({ title: desc });
            // provide completion list inside this string literal showing 
            // todoDescriptionChanged to avoid hard to debug typos 
            // and speed up development
            todo.trigger('todoDescriptionChanged'); 
        }
     }"><pre class="notranslate">    <span class="pl-en">updateTodo</span><span class="pl-kos">(</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">desc</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">$input</span><span class="pl-kos">.</span><span class="pl-en">val</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">trim</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">todo</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">model</span><span class="pl-kos">;</span>
        <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-s1">desc</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
            <span class="pl-s1">todo</span><span class="pl-kos">.</span><span class="pl-en">save</span><span class="pl-kos">(</span><span class="pl-kos">{</span> <span class="pl-c1">title</span>: <span class="pl-s1">desc</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
            <span class="pl-c">// provide completion list inside this string literal showing </span>
            <span class="pl-c">// todoDescriptionChanged to avoid hard to debug typos </span>
            <span class="pl-c">// and speed up development</span>
            <span class="pl-s1">todo</span><span class="pl-kos">.</span><span class="pl-en">trigger</span><span class="pl-kos">(</span><span class="pl-s">'todoDescriptionChanged'</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">This should be a relatively cheap solution to a common set of problems that we've always hoped TypeScript can improve on over JavaScript. If you did accidentally make a typo in one use of the literal this could also help you discover that when seeing 2 completion list items that are similar but slightly different.</p>