Start learning free

LESSON 64 OF 348 · STRINGS I

String Immutability in TypeScript: Replacing, Not Editing

Lesson Read the full explanation

In TypeScript, strings are immutable, which means that they cannot be altered once created.

For example, the following code:

let message = "Jello world";

message[0] = 'H';

console.log(message);

would output:

Jello world

As you can see, the program executes but the string wasn't changed after all. Some languages like Python wouldn't even let this code run, but throw a TypeError. TypeScript is more permissive, which is not necessary a good thing.

As a programmer, I'd rather be told when I made a mistake early on so I can fix it, instead of running into problems later on and not knowing what the root of those problems is.


Variable can still be changed:

Note that this does not mean that message cannot be changed, just that the individual characters of a string literal cannot be changed.

"Jello world" is a string literal that TypeScript stores in memory, while message is a variable that refers to that string literal.

When we do message[0] = 'H', we are trying to alter the string literal "Jello world", which is not allowed.

But like any other variable, message can be changed by reassigning it with a new string, like this:

let message = "Jello world";

message = "Hello world";

console.log(message);

This code would output:

Hello world

Instead of trying to alter the first string, this code now creates a new one ("Hello world"), stores it in memory and tells message to refer to this new string.


Assignment
Follow the Coding Tutorial and let's practice with string immutability!


Hint
Look at the examples above if you get stuck.


STEP 1 OF 1
    Ctrl + Enter to check

    TYPESCRIPT · STRINGS I

    String Immutability in TypeScript, explained

    What immutable means

    Strings in TypeScript are immutable: once a string exists, none of its characters can be changed. You can read the character at an index, but you can't write to it.

    let message = "Jello world";
    message[0] = 'H';
    

    This code is rejected twice. The compiler reports error TS2542: Index signature in type 'String' only permits reading. If the JavaScript runs anyway, as it does in the lessons, the assignment fails when it executes:

    TypeError: Cannot assign to read only property '0' of string 'Jello world'
    

    Compiled TypeScript runs in JavaScript's strict mode, which turns the failed write into an error. In old non-strict scripts the same assignment would be silently ignored and message would still be "Jello world". Either way, the string does not change.

    Variables are not strings

    Immutability applies to the string value, not to the variable that holds it. A variable declared with let is a label that can be moved to a different string at any time:

    let message = "Jello world";
    message = "Hello world";
    console.log(message);
    
    Hello world
    

    Nothing edited "Jello world". The second line created a different string, "Hello world", and made message refer to it. The first string is simply no longer used.

    Making a changed copy

    To "change" one character, build a new string from the parts you want to keep. Take the original apart with substring or slice, then join the pieces with +:

    let a = "abc";
    let b = a.toUpperCase();
    console.log(a, b);
    
    abc ABC
    

    The same rule applies to every string method, such as toUpperCase, slice and replace. They return a new string and leave the original as it was. If you want the result, you must store it, either in a new variable or back into the same one.

    When you really need to modify individual characters, turn the string into an array, change the array and join it back:

    const chars = Array.from("bndrei");
    chars[0] = "A";
    console.log(chars.join(""));
    
    Andrei
    

    Arrays are mutable, so the assignment is allowed. For a single replacement, though, the slicing approach is simpler.

    The exercise

    The starter code stores a name with a typo, and tries to fix it by assigning to an index:

    let name: string = "bndrei Chiriac";
    // Change code below:
    name[0] = 'A';
    

    The program stops with TypeError: Cannot assign to read only property '0' of string 'bndrei Chiriac'. The task is to make name hold "Andrei Chiriac".

    1. Keep everything after the first character. name.substring(1) returns the string without its first character: "ndrei Chiriac".
    2. Put the correct first letter in front with "A" + .... The result is a new string, "Andrei Chiriac".
    3. Assign it back to name. This is allowed, because it replaces the whole value instead of editing one position.
    let name: string = "bndrei Chiriac";
    // Change code below:
    name = "A" + name.substring(1);
    

    Now name holds Andrei Chiriac. The right-hand side is evaluated using the old value, and only then is the variable updated.

    Why languages do this

    Immutable strings are safe to share. If two variables refer to the same string, neither can change it behind the other's back. The price is that building a long text by many small edits creates many intermediate strings, which is rarely a concern at the scale of this chapter. Other values behave differently: arrays and objects are mutable, so an assignment to one of their elements or properties does change the value.

    Gotchas

    • The error is about the string, not the variable. let is not the issue here. Even a variable that can be reassigned can't have its string value edited in place.
    • Methods don't modify. A line like name.toUpperCase(); on its own has no effect on name.
    • Type annotations don't change this. Writing : string only tells the compiler what the variable holds. The immutability is a property of the string value itself.
    • A const variable can't be reassigned. The exercise's fix needs let.

    Key takeaways

    • You can't assign to string[index]; the compiler and the run-time both refuse it.
    • A variable can be reassigned to a new string.
    • String methods return new strings and never alter the original.
    • To change part of a string, join slices of it with the new text.
    Keep going with TypeScriptAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free