<p dir="auto">I've got an opaque string type. We basically use this type for things that are strings under the hood, but shouldn't be interchanged with actual free text strings- for example GUIDs. We also use the nominal type checking hack with the private void property to nominally type check them.</p>
<p dir="auto">We have a problem, though, which is that the compiler won't permit them as dictionary keys.</p>
<p dir="auto">Can we permit a type annotation or something to say that the type is really a string or integer under the hood and should be permitted as a dictionary key?</p>
<p dir="auto"><code class="notranslate">IDBKeyRange</code> is defined as follows.</p>
<p dir="auto"><a href="https://github.com/Microsoft/TypeScript/blob/master/bin/lib.d.ts#L11630">https://github.com/Microsoft/TypeScript/blob/master/bin/lib.d.ts#L11630</a></p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="interface IDBKeyRange {
    upper: any;
    upperOpen: boolean;
    lower: any;
    lowerOpen: boolean;
}
declare var IDBKeyRange: {
    prototype: IDBKeyRange;
    new(): IDBKeyRange;
    bound(lower: any, upper: any, lowerOpen?: boolean, upperOpen?: boolean): IDBKeyRange;
    only(value: any): IDBKeyRange;
    lowerBound(bound: any, open?: boolean): IDBKeyRange;
    upperBound(bound: any, open?: boolean): IDBKeyRange;
}"><pre class="notranslate"><span class="pl-k">interface</span> <span class="pl-smi">IDBKeyRange</span> <span class="pl-kos">{</span>
    <span class="pl-c1">upper</span>: <span class="pl-smi">any</span><span class="pl-kos">;</span>
    <span class="pl-c1">upperOpen</span>: <span class="pl-smi">boolean</span><span class="pl-kos">;</span>
    <span class="pl-c1">lower</span>: <span class="pl-smi">any</span><span class="pl-kos">;</span>
    <span class="pl-c1">lowerOpen</span>: <span class="pl-smi">boolean</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>
<span class="pl-k">declare</span> <span class="pl-k">var</span> <span class="pl-smi">IDBKeyRange</span>: <span class="pl-kos">{</span>
    <span class="pl-c1">prototype</span>: <span class="pl-smi">IDBKeyRange</span><span class="pl-kos">;</span>
    <span class="pl-k">new</span><span class="pl-kos">(</span><span class="pl-kos">)</span>: <span class="pl-smi">IDBKeyRange</span><span class="pl-kos">;</span>
    <span class="pl-c1">bound</span><span class="pl-kos">(</span><span class="pl-s1">lower</span>: <span class="pl-smi">any</span><span class="pl-kos">,</span> <span class="pl-s1">upper</span>: <span class="pl-smi">any</span><span class="pl-kos">,</span> <span class="pl-s1">lowerOpen</span>?: <span class="pl-smi">boolean</span><span class="pl-kos">,</span> <span class="pl-s1">upperOpen</span>?: <span class="pl-smi">boolean</span><span class="pl-kos">)</span>: <span class="pl-smi">IDBKeyRange</span><span class="pl-kos">;</span>
    <span class="pl-c1">only</span><span class="pl-kos">(</span><span class="pl-s1">value</span>: <span class="pl-smi">any</span><span class="pl-kos">)</span>: <span class="pl-smi">IDBKeyRange</span><span class="pl-kos">;</span>
    <span class="pl-c1">lowerBound</span><span class="pl-kos">(</span><span class="pl-s1">bound</span>: <span class="pl-smi">any</span><span class="pl-kos">,</span> <span class="pl-s1">open</span>?: <span class="pl-smi">boolean</span><span class="pl-kos">)</span>: <span class="pl-smi">IDBKeyRange</span><span class="pl-kos">;</span>
    <span class="pl-c1">upperBound</span><span class="pl-kos">(</span><span class="pl-s1">bound</span>: <span class="pl-smi">any</span><span class="pl-kos">,</span> <span class="pl-s1">open</span>?: <span class="pl-smi">boolean</span><span class="pl-kos">)</span>: <span class="pl-smi">IDBKeyRange</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">But it does not work.</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="new IDBKeyRange(); // error"><pre class="notranslate"><span class="pl-k">new</span> <span class="pl-v">IDBKeyRange</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// error</span></pre></div>
<p dir="auto">Please recovery.</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="interface IDBKeyRange {
    upper: any;
    upperOpen: boolean;
    lower: any;
    lowerOpen: boolean;
    bound(lower: any, upper: any, lowerOpen?: boolean, upperOpen?: boolean): IDBKeyRange;
    only(value: any): IDBKeyRange;
    lowerBound(bound: any, open?: boolean): IDBKeyRange;
    upperBound(bound: any, open?: boolean): IDBKeyRange;
}
"><pre class="notranslate"><span class="pl-k">interface</span> <span class="pl-smi">IDBKeyRange</span> <span class="pl-kos">{</span>
    <span class="pl-c1">upper</span>: <span class="pl-smi">any</span><span class="pl-kos">;</span>
    <span class="pl-c1">upperOpen</span>: <span class="pl-smi">boolean</span><span class="pl-kos">;</span>
    <span class="pl-c1">lower</span>: <span class="pl-smi">any</span><span class="pl-kos">;</span>
    <span class="pl-c1">lowerOpen</span>: <span class="pl-smi">boolean</span><span class="pl-kos">;</span>
    <span class="pl-c1">bound</span><span class="pl-kos">(</span><span class="pl-s1">lower</span>: <span class="pl-smi">any</span><span class="pl-kos">,</span> <span class="pl-s1">upper</span>: <span class="pl-smi">any</span><span class="pl-kos">,</span> <span class="pl-s1">lowerOpen</span>?: <span class="pl-smi">boolean</span><span class="pl-kos">,</span> <span class="pl-s1">upperOpen</span>?: <span class="pl-smi">boolean</span><span class="pl-kos">)</span>: <span class="pl-smi">IDBKeyRange</span><span class="pl-kos">;</span>
    <span class="pl-c1">only</span><span class="pl-kos">(</span><span class="pl-s1">value</span>: <span class="pl-smi">any</span><span class="pl-kos">)</span>: <span class="pl-smi">IDBKeyRange</span><span class="pl-kos">;</span>
    <span class="pl-c1">lowerBound</span><span class="pl-kos">(</span><span class="pl-s1">bound</span>: <span class="pl-smi">any</span><span class="pl-kos">,</span> <span class="pl-s1">open</span>?: <span class="pl-smi">boolean</span><span class="pl-kos">)</span>: <span class="pl-smi">IDBKeyRange</span><span class="pl-kos">;</span>
    <span class="pl-c1">upperBound</span><span class="pl-kos">(</span><span class="pl-s1">bound</span>: <span class="pl-smi">any</span><span class="pl-kos">,</span> <span class="pl-s1">open</span>?: <span class="pl-smi">boolean</span><span class="pl-kos">)</span>: <span class="pl-smi">IDBKeyRange</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>