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".
- Keep everything after the first character.
name.substring(1)returns the string without its first character:"ndrei Chiriac". - Put the correct first letter in front with
"A" + .... The result is a new string,"Andrei Chiriac". - 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.
letis 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 onname. - Type annotations don't change this. Writing
: stringonly tells the compiler what the variable holds. The immutability is a property of the string value itself. - A
constvariable can't be reassigned. The exercise's fix needslet.
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.