<p dir="auto"><code class="notranslate">const</code> cannot be applied to instance variables, but it would be nice if we can declare immutable instance variables (with <code class="notranslate">final</code> keyword, for example).</p>
<p dir="auto">Will there be support for this functionality?</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="class Foo {
    private final str = 'str';
    private final num: number;
    constructor(private final bool: boolean) {
        this.num = 0;
    }

    doSomething() {
        // The below codes raise compilation errors
        this.str = '';
        this.num = 0;
        this.bool = false;
    }
}"><pre class="notranslate"><span class="pl-k">class</span> <span class="pl-smi">Foo</span> <span class="pl-kos">{</span>
    <span class="pl-k">private</span> <span class="pl-c1">final</span> <span class="pl-s1">str</span> <span class="pl-c1">=</span> <span class="pl-s">'str'</span><span class="pl-kos">;</span>
    <span class="pl-k">private</span> <span class="pl-c1">final</span> <span class="pl-s1">num</span>: <span class="pl-smi">number</span><span class="pl-kos">;</span>
    <span class="pl-en">constructor</span><span class="pl-kos">(</span><span class="pl-k">private</span> <span class="pl-s1">final</span> <span class="pl-s1">bool</span>: <span class="pl-smi">boolean</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-c1">num</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>

    <span class="pl-en">doSomething</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
        <span class="pl-c">// The below codes raise compilation errors</span>
        <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">str</span> <span class="pl-c1">=</span> <span class="pl-s">''</span><span class="pl-kos">;</span>
        <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">num</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span><span class="pl-kos">;</span>
        <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">bool</span> <span class="pl-c1">=</span> <span class="pl-c1">false</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">Some properties in JavaScript are actually read-only, i.e. writes to them either fail silently or cause an exception. These should be modelable in TypeScript.</p>
<p dir="auto">Previous attempts to design this have run into problems. A brief exploration:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="interface Point {
    x: number;
    y: number;
}
interface ImmutablePoint {
    readonly x: number;
    readonly y: number;
}
var pt: ImmutablePoint = { x: 4, y: 5 }; // OK, can convert mutable to non-mutable
pt.x = 5; // Error, 'pt.x' is not a valid target of assignment

var pt2: Point = pt; // Error, cannot convert readonly 'x' to mutable 'x'

// Possibly bad behavior
var pt3: Point = { x: 1, y: 1 };
var pt4: ImmutablePoint = pt3; // OK
pt3.x = 5; // pt4.x is also changed?

// Really bad behavior
/** This function was written in TypeScript 1.0 **/
function magnitudeSquared(v: { x: number; y: number }) {
   return v.x * v.x + v.y * v.y;
}
// Now try to use it with ImmutablePoint
console.log(magnitudeSquared(pt)); // Error, cannot use readonly object in non-readonly call"><pre class="notranslate"><span class="pl-k">interface</span> <span class="pl-smi">Point</span> <span class="pl-kos">{</span>
    <span class="pl-c1">x</span>: <span class="pl-smi">number</span><span class="pl-kos">;</span>
    <span class="pl-c1">y</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">ImmutablePoint</span> <span class="pl-kos">{</span>
    <span class="pl-k">readonly</span> <span class="pl-c1">x</span>: <span class="pl-smi">number</span><span class="pl-kos">;</span>
    <span class="pl-k">readonly</span> <span class="pl-c1">y</span>: <span class="pl-smi">number</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>
<span class="pl-k">var</span> <span class="pl-s1">pt</span>: <span class="pl-smi">ImmutablePoint</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">x</span>: <span class="pl-c1">4</span><span class="pl-kos">,</span> <span class="pl-c1">y</span>: <span class="pl-c1">5</span> <span class="pl-kos">}</span><span class="pl-kos">;</span> <span class="pl-c">// OK, can convert mutable to non-mutable</span>
<span class="pl-s1">pt</span><span class="pl-kos">.</span><span class="pl-c1">x</span> <span class="pl-c1">=</span> <span class="pl-c1">5</span><span class="pl-kos">;</span> <span class="pl-c">// Error, 'pt.x' is not a valid target of assignment</span>

<span class="pl-k">var</span> <span class="pl-s1">pt2</span>: <span class="pl-smi">Point</span> <span class="pl-c1">=</span> <span class="pl-s1">pt</span><span class="pl-kos">;</span> <span class="pl-c">// Error, cannot convert readonly 'x' to mutable 'x'</span>

<span class="pl-c">// Possibly bad behavior</span>
<span class="pl-k">var</span> <span class="pl-s1">pt3</span>: <span class="pl-smi">Point</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">x</span>: <span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">y</span>: <span class="pl-c1">1</span> <span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-s1">pt4</span>: <span class="pl-smi">ImmutablePoint</span> <span class="pl-c1">=</span> <span class="pl-s1">pt3</span><span class="pl-kos">;</span> <span class="pl-c">// OK</span>
<span class="pl-s1">pt3</span><span class="pl-kos">.</span><span class="pl-c1">x</span> <span class="pl-c1">=</span> <span class="pl-c1">5</span><span class="pl-kos">;</span> <span class="pl-c">// pt4.x is also changed?</span>

<span class="pl-c">// Really bad behavior</span>
<span class="pl-c">/** This function was written in TypeScript 1.0 **/</span>
<span class="pl-k">function</span> <span class="pl-en">magnitudeSquared</span><span class="pl-kos">(</span><span class="pl-s1">v</span>: <span class="pl-kos">{</span> <span class="pl-c1">x</span>: <span class="pl-smi">number</span><span class="pl-kos">;</span> <span class="pl-c1">y</span>: <span class="pl-smi">number</span> <span class="pl-kos">}</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
   <span class="pl-k">return</span> <span class="pl-s1">v</span><span class="pl-kos">.</span><span class="pl-c1">x</span> <span class="pl-c1">*</span> <span class="pl-s1">v</span><span class="pl-kos">.</span><span class="pl-c1">x</span> <span class="pl-c1">+</span> <span class="pl-s1">v</span><span class="pl-kos">.</span><span class="pl-c1">y</span> <span class="pl-c1">*</span> <span class="pl-s1">v</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-c">// Now try to use it with ImmutablePoint</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-en">magnitudeSquared</span><span class="pl-kos">(</span><span class="pl-s1">pt</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// Error, cannot use readonly object in non-readonly call</span></pre></div>
<p dir="auto">Possible solutions?</p>
<ul dir="auto">
<li>Allow bivariance of mutability: this is very unsound</li>
<li>Something else clever? C++ did not do well with const contamination</li>
</ul>