Start learning free

TYPESCRIPT · STRINGS

Intro To Strings in TypeScript, explained

What a string is

A string is a sequence of characters: a word, a sentence, a number written as text, or even nothing at all. In TypeScript, strings have the type string (lowercase). You write a string value, called a string literal, between quotes:

const first: string = "Hello";
const second: string = 'Hello';
const empty: string = "";

Single and double quotes make exactly the same string. Pick one style and keep it. The only practical difference is which quote you can write inside without extra effort: "it's" and 'say "hi"' both work as written.

The type annotation is optional here. TypeScript infers string from the literal, so const first = "Hello" has the same type.

Length and indexes

Every string has a length property, and every character sits at an index that starts at 0. Square brackets read the character at an index, and the result is itself a string of length one. TypeScript has no separate character type.

const s: string = "Hello";
console.log(s.length);         // 5
console.log(s[0]);             // H
console.log(s[s.length - 1]);  // o
console.log(s[10]);            // undefined

The last valid index is always length - 1. Reading past the end doesn't fail: it gives undefined, even though the compiler describes s[10] as a string. That is a common source of surprises in loops that run one step too far.

Strings are immutable

A string can't be changed after it is created. You can read s[0], but you can't assign to it. The compiler rejects an assignment like myStr[0] = "J" with the message "Index signature in type 'String' only permits reading". Even if you get past the compiler, the string stays as it was: at run time the assignment either throws a TypeError or is silently ignored, depending on whether the code runs in strict mode.

What you can do is build a new string and store it back in a variable declared with let:

let myStr: string = "Bob";
myStr = "J" + myStr.slice(1);
console.log(myStr); // Job

The old "Bob" was not modified. The variable now refers to a different string. This matters for performance too: building a long string one character at a time creates many intermediate strings, and the cost depends on how the engine handles them.

Joining strings

The + operator joins two strings. The += operator joins and stores the result back in one step:

let greet: string = "Welcome";
greet += " to the course, ";
greet += "Ana";
console.log(greet); // Welcome to the course, Ana

Be careful when a number is involved. If either side of + is a string, the other side is converted to text and the two are joined. Evaluation goes from left to right, so the position of the string decides what happens:

const s: string = "Hello";
console.log(s + 1 + 2); // Hello12
console.log(1 + 2 + s); // 3Hello

In the second line, 1 + 2 is added as numbers first, and only then is the result joined to the string.

Template literals, written with backticks, put values inside a string with ${...}. They are often easier to read than a chain of +:

const n: number = s.length;
console.log(`"${s}" has ${n} characters`); // "Hello" has 5 characters

Common string methods

Because strings can't change, every method that seems to modify a string returns a new one and leaves the original alone. These are the ones you'll use most in this chapter:

MethodWhat it doesExample on "Hello"
slice(start, end)Part of the string from start up to, but not including, endslice(1, 3) gives "el"
slice(start)Everything from start to the endslice(-2) gives "lo"
indexOf(text)Index of the first match, or -1indexOf("l") gives 2
includes(text)true or falseincludes("ell") gives true
toUpperCase()A copy in capitals"HELLO"
split(separator)An array of piecessplit("") gives ["H", "e", "l", "l", "o"]

A negative index in slice counts from the end, which is handy for "the last two characters". Square-bracket indexing doesn't do that: s[-1] is undefined.

Comparing strings

Use === to check whether two strings hold the same characters. It compares the text, not the identity of the string:

console.log("apple" === "app" + "le"); // true
console.log("a" < "b");                  // true

The comparison is case-sensitive, so "Hello" === "hello" is false. The operators < and > compare character codes one by one, which is why all capital letters sort before all lowercase ones.

Looping over a string

There are two usual ways. With for...of you get each character directly. With an index loop you also know the position:

const word: string = "Andy";
for (const c of word) {
    console.log(c);
}
for (let i = 0; i < word.length; i++) {
    console.log(i, word[i]);
}

Both visit every character once, so they take time proportional to the length of the string.

Characters, code units and emoji

Under the hood, a TypeScript string is a sequence of 16-bit units, and length and indexing count those units. Most letters take one unit, but some characters, including many emoji, take two. For such a character, "😀".length is 2, while [..."😀"].length is 1 because for...of and the spread syntax walk over whole characters instead. For the plain letters and digits in this chapter's exercises, the two views agree.

Strings and the type system

Types disappear when TypeScript is compiled to JavaScript, so an annotation never converts anything. If a value that is really a number is typed as string through a cast, it stays a number at run time: typeof still says "number". Convert on purpose with String(value) or value.toString() for numbers to text, and Number(text) for text to numbers.

Key takeaways

  • A string is a sequence of characters with the type string, written in single quotes, double quotes or backticks.
  • Indexes start at 0 and the last one is length - 1. Reading outside gives undefined.
  • Strings are immutable: methods return new strings, and you store the result in a variable.
  • + joins strings, and a string on either side turns the other side into text.
  • Compare strings with ===, and loop over them with for...of or an index.
  • Next in the chapter come slicing, splitting and rebuilding strings, which put these ideas to work.
Keep going with TypeScriptAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
Start learning free