cf.completefrontend
Open lab My progress
THE TYPESCRIPT FIELD GUIDE

Primitive types

Learn TypeScript's seven primitive types, from string and number to bigint and symbol, why you write them in lowercase, and what types your constants get.

By the end, you can
  • 01
    Name the seven primitive typesWrite string, number, boolean, bigint, symbol, null, and undefined, and say which values each one holds.
  • 02
    Pick lowercase typesExplain why string is right and String is a wrapper object, and read the error TypeScript gives when they meet.
  • 03
    Read the type of a constantSay why const minOrder = 50 has the type 50 while a let gets number, and when an annotation changes that.

Seven kinds of simple values

A user profile on a shop site holds a few simple values: a name, an age, whether the user is a member. JavaScript calls simple values like these primitives. A primitive is one plain value, like "Asha" or 31, with nothing stored inside it. JavaScript has seven kinds of them (the Data types lesson covers each one), and TypeScript has a type for each kind.

As in the last lesson, you write a type after a name with a colon: age: number means "age must hold a number". That is a type annotation. Here is one value of every kind, each with its type:

One value of each primitive typePop out in the code editor (opens in a new tab)TypeScript
const userName: string = "Asha";const age: number = 31;const isMember: boolean = true;const profileViews: bigint = 9007199254740993n;const sessionKey: symbol = Symbol("session");const coupon: null = null;const nickname: undefined = undefined;console.log(typeof userName, typeof age, typeof isMember, typeof profileViews);console.log(typeof sessionKey, typeof coupon, typeof nickname);

Line by line:

  • Lines 1 to 3 are the three you'll write most: string for text, number for numbers, and boolean for true or false.
  • Line 4 is a bigint, a whole number of any size. The n at the end makes it one.
  • Line 5 is a symbol, a unique value made by Symbol().
  • Lines 6 and 7 are null and undefined, two ways to say "nothing here". Each one is a type with exactly one value.
  • Line 8 prints string number boolean bigint and line 9 prints symbol object undefined. JavaScript's typeof gives back the name of a value's kind (Checking types covers it).

TypeScript reports no errors: every value matches its type. Notice the type names are the same words typeof prints. That's on purpose. There is one exception, null:

Each value, what typeof says, and its TypeScript type
The valueWhat typeof saysIts TypeScript type
"Asha""string"string
31"number"number
true"boolean"boolean
9007199254740993n"bigint"bigint
Symbol("session")"symbol"symbol
null"object", an old JavaScript mistake.null
undefined"undefined"undefined

Read each row as: this value, what JavaScript's typeof prints for it, and the type you write in TypeScript. typeof null prints "object" because of a mistake in the first version of JavaScript that can't be fixed without breaking old pages. TypeScript gives null its own type, named null.

Seven value cards, each with its type under it. Top row: "Asha" is a string, 31 is a number, true is a boolean, 9007199254740993n is a bigint. Bottom row: Symbol("session") is a symbol, null is null, undefined is undefined."Asha"string31numbertrueboolean9007199254740993nbigintSymbol("session")symbolnullnullundefinedundefinedone simple value on each card
One value of each primitive type from the example. Each type name is lowercase and has its own kind of value: text, numbers, true or false, big whole numbers, unique keys, and two ways to say "nothing here".
Real-life analogyBoxes on a paper form

At a bank, you fill in a paper form. Each box takes one kind of short answer: letters for your name, digits for your age, a tick for "member?". Some boxes you leave blank, and some you fill with "none" on purpose. Before the form is filed, the clerk checks that each answer is the kind its box asks for.

In real life: The name box takes letters
In TypeScript: string holds text: userName: string
In real life: The age box takes digits
In TypeScript: number holds numbers: age: number
In real life: The "member?" box takes a tick or no tick
In TypeScript: boolean holds true or false
In real life: The long account-number box has room for every digit
In TypeScript: bigint keeps every digit of a big whole number
In real life: The ticket number printed on top matches no other form
In TypeScript: symbol is a value equal to no other
In real life: A box left blank, and a box where you wrote "none"
In TypeScript: undefined (nothing stored yet) and null (empty on purpose)
In real life: The clerk spots words in the age box before filing the form
In TypeScript: TypeScript marks "31" going into a number before the code runs
The main idea

A primitive type names one kind of simple value. TypeScript has seven: string, number, boolean, bigint, symbol, null, and undefined. You write them in lowercase, after a colon: age: number.

string, number, and boolean

Most values on a page are text, numbers, or yes-or-no answers. Here is one of each for a product on a shop page:

A product's name, price, and stockPop out in the code editor (opens in a new tab)TypeScript
let title: string = "Green tea";let price: number = 3.5;let inStock: boolean = true; price = 4;inStock = false;console.log(title, price, inStock);

Line 1 says title is a string: any text, short or long, in single quotes, double quotes, or backticks (Strings). Line 2 says price is a number. Line 3 says inStock is a boolean: true or false, nothing else (Booleans).

These are let variables, so they can change. Line 5 puts a new price in, and line 6 marks the product sold out. Both new values match their types, so there are no errors. Line 7 prints Green tea 4 false.

Some languages have one type for whole numbers and another for decimals. TypeScript doesn't, because JavaScript doesn't: 3, 3.5, -3, and even NaN are all numbers (Numbers). Try it. Type a discount on line 2 and watch the list under the code:

Playground: what fits in a number
A price and a discountPop out in the code editor (opens in a new tab)TypeScript
const price: number = 20;const discount: number = 5;console.log(price - discount);
Line 2 holds5
What happens
TypeScriptNo errors
When it runsprints 15
Try it yourself

5 is a number, so line 2 matches its type. There are no errors, and 20 - 5 prints 15.

The code is checked by the real TypeScript compiler each time you type. Only line 2 changes. Reset puts 5 back.

2.5, -5, and NaN are all numbers, so the errors stay away. "5" in quotes is text, true is a boolean, and 5n is a bigint, so each one gets Type '…' is not assignable to type 'number'. That message means "this kind of value can't be stored where a number has to go". TypeScript checks the kind of value, not whether it's a sensible discount: a negative one is fine.

A type also decides what you can do with a value. Strings have text methods like toUpperCase(), and numbers have number methods like toFixed(), which rounds to a number of decimal places. Mix them up and TypeScript notices:

A number has no toUpperCase (an error on purpose)Pop out in the code editor (opens in a new tab)TypeScript
const title: string = "Green tea";const price: number = 3.5;console.log(title.toUpperCase());console.log(price.toFixed(2));console.log(price.toUpperCase());

Line 3 prints GREEN TEA, and line 4 prints 3.50. Line 5 calls toUpperCase() on the price. TypeScript marks it, on purpose here: Property 'toUpperCase' does not exist on type 'number'. In plain words: "a number has no method with that name". When the code runs, line 5 throws a TypeError and stops. The same knowledge drives your editor's suggestions: type price. and it lists only number methods.

null and undefined

JavaScript has two values that mean "nothing here". undefined is what you get when nothing was ever stored, like a variable with no value yet. null is a value you store on purpose to say "empty", like a coupon box the shopper cleared (null and undefined cover both).

In TypeScript, each is its own type, with exactly one value. A string can't hold either of them:

Nothing isn't a string (an error on purpose)Pop out in the code editor (opens in a new tab)TypeScript
let coupon: string = "SAVE10";coupon = null; let nickname: string = undefined;

Line 1 gives coupon the text "SAVE10". Line 2 clears it with null, and TypeScript marks it: Type 'null' is not assignable to type 'string'. Line 4 tries to start nickname as undefined and gets the same error for undefined. Both are on purpose. If they got through, a later coupon.toUpperCase() would throw, because null has no methods.

This check comes from a compiler option called strictNullChecks. It is part of strict, the set of checks most projects turn on, and every example in these lessons uses it. Here is the same code with that one option turned off; the list under the code shows the option:

The same code with strictNullChecks offPop out in the code editor (opens in a new tab)TypeScript
let coupon: string = "SAVE10";coupon = null; let nickname: string = undefined;console.log(coupon, nickname);

Now null and undefined fit into any type, so there are no errors, and line 5 prints null undefined. That's how TypeScript worked before the option existed. Keep it on: without it, a missing value hides inside a string until the page throws.

The types null and undefined themselves look like this:

The null and undefined typesPop out in the code editor (opens in a new tab)TypeScript
const coupon = null;//    ^?const nickname: undefined = undefined;console.log(typeof coupon, typeof nickname);

The query on line 2 shows TypeScript gives coupon the type null. Line 3 annotates nickname as undefined. Line 4 prints object undefined: the old typeof null mistake again. A name that can only ever hold null isn't much use on its own. You'll mostly use these two types together with another one, as in "a string, or null when the coupon is empty". The Union types and null, undefined & strictNullChecks lessons show how.

Lowercase string, not String

TypeScript also has types called String, Number, and Boolean, with capital letters. They look like the same thing. They aren't. String is the type of a wrapper object: an object made with new String("Pune") that holds the text inside it (Methods of primitives explains wrappers).

A String object isn't a string (an error on purpose)Pop out in the code editor (opens in a new tab)TypeScript
const city: string = "Pune";const boxedCity: String = new String("Pune");const copy: string = boxedCity;console.log(typeof city, typeof boxedCity);

Line 1 is a plain string. Line 2 makes a String object. Line 3 tries to store that object in a string, and TypeScript marks it on purpose with a message in two parts:

  • Type 'String' is not assignable to type 'string': the object can't go where plain text has to go.
  • 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. TypeScript even tells you which one to write.

Line 4 prints string object: to JavaScript, the wrapper really is an object. The mix-up usually starts the other way round, because TypeScript lets plain text go into a String without complaint:

A capital String takes text without an errorPop out in the code editor (opens in a new tab)TypeScript
const label: String = "Order";//    ^?console.log(label.toUpperCase());

Line 1 annotates label with String, and the query on line 2 confirms that is its type. There are no errors, and line 3 prints ORDER. So code with a capital String seems to work, until you pass label to something that needs a string and get the error from the example before. Write the lowercase types every time:

Left, string: a single card with "Pune" on it, the text itself, made by writing "Pune". Right, String: a cart labelled String holding the card "Pune", an object around the text, made with new String("Pune")."Pune""Pune"stringthe text itselfnew String("Pune")"Pune"Stringan object around it
string is the text itself. String is an object wrapped around the text, which only new String(…) makes. Your values are almost always the plain text, so write string.

The table below lists both spellings. Read each row as: this type, what it describes, and whether to write it.

Lowercase and capital type names
The typeWhat it describesShould you write it?
stringA text value, like "Pune".Yes. Use it for all text.
StringA String wrapper object, made with new String("Pune").No. Real code almost never makes these objects.
number and booleanA number like 3.5, or true or false.Yes. Use them for all numbers and true-or-false values.
Number and BooleanWrapper objects made with new Number(3.5) or new Boolean(false).No. Use the lowercase types.

bigint and symbol

A number keeps whole numbers exact only up to 9007199254740991. Past that, it rounds. A bigint holds a whole number of any size exactly. You write one with an n at the end (BigInt):

A view count too big for a numberPop out in the code editor (opens in a new tab)TypeScript
const numberViews: number = 9007199254740993;const totalViews: bigint = 9007199254740993n;console.log(numberViews);console.log(totalViews + 1n);

Line 1 stores 9007199254740993 in a number. Line 2 stores the same digits in a bigint. Line 3 prints 9007199254740992: the number was rounded to the nearest value it can hold, with no warning. Line 4 adds 1n, another bigint, and prints 9007199254740994n, exactly right.

Top row, number: 9007199254740993 goes in, and 9007199254740992 is stored, rounded. Bottom row, bigint: 9007199254740993n goes in, and 9007199254740993n is stored, every digit kept.number90071992547409939007199254740992roundedbigint9007199254740993n9007199254740993nevery digit kept
Line 1 asks a number to hold 9007199254740993, and it stores 9007199254740992, the nearest number it can hold. Line 2's bigint keeps every digit.

number and bigint are different types, and JavaScript refuses to mix them in a sum. TypeScript tells you before it runs:

Adding a number to a bigint (an error on purpose)Pop out in the code editor (opens in a new tab)TypeScript
const totalViews: bigint = 9007199254740993n;const newViews: number = 1;console.log(totalViews + newViews);

Line 3 adds newViews, a number, to a bigint. TypeScript marks it on purpose: Operator '+' cannot be applied to types 'bigint' and 'number', which means "+ doesn't work with one of each". When it runs, JavaScript throws TypeError: Cannot mix BigInt and other types. The fix is to turn the number into a bigint first:

Turning the number into a bigint firstPop out in the code editor (opens in a new tab)TypeScript
const totalViews: bigint = 9007199254740993n;const newViews: number = 1;console.log(totalViews + BigInt(newViews));

Line 3 now wraps newViews in BigInt(…), which gives back 1n. Both sides are bigints, the error is gone, and it prints 9007199254740994n.

The table below compares the two number types. Read each row as a question, then each type's answer.

number and bigint, side by side
Questionnumberbigint
Which values does it hold?Whole numbers and decimals, like 3 and 3.5.Whole numbers only, written with an n, like 10n.
How big can it be and stay exact?Up to 9007199254740991. Bigger whole numbers can get rounded.Any size. Every digit is kept.
Can you add it to the other one with +?No. TypeScript reports it, and JavaScript throws a TypeError.No. Turn one into the other first.
What turns the other one into this one?Number(10n) gives 10.BigInt(10) gives 10n.

Bigints arrived in JavaScript in 2020, so TypeScript only accepts the n when your project targets a JavaScript version from 2020 or later. The target option says which version your code must run on. This example sets it to 2019:

A bigint for an older target (an error on purpose)Pop out in the code editor (opens in a new tab)TypeScript
const totalViews: bigint = 9007199254740993n;console.log(totalViews);

Line 1 gets BigInt literals are not available when targeting lower than ES2020. "BigInt literal" means a number written with an n, and ES2020 is the 2020 version of JavaScript. The browser running this page is newer, so it still prints 9007199254740993n, but an older browser couldn't run it. These lessons target ES2022, so bigints work everywhere else on the page.

The last primitive is symbol. Every call to Symbol() makes a brand-new value that equals no other, even with the same description. Symbols are used as hidden property keys, such as a key a library stores on your objects without clashing with your own names (Symbols).

Two session symbolsPop out in the code editor (opens in a new tab)TypeScript
const sessionKey = Symbol("session");//    ^?let currentKey = Symbol("session");//  ^?console.log(sessionKey === currentKey);console.log(sessionKey.description);

The query on line 4 shows let currentKey: symbol: any symbol may go in it later. The query on line 2 shows something new: const sessionKey: typeof sessionKey. Because a const symbol can never be swapped for another, TypeScript gives it a type of its own, which only this one symbol has. (Its name is unique symbol; you'll rarely write it.) Line 5 prints false, because two calls make two different symbols. Line 6 prints session, the description you passed in.

That type of its own lets TypeScript spot a comparison that can never be true:

Comparing two different symbols (an error on purpose)Pop out in the code editor (opens in a new tab)TypeScript
const cartKey = Symbol("cart");const savedKey = Symbol("cart");console.log(cartKey === savedKey);

Lines 1 and 2 make two const symbols with the same description. Line 3 compares them, and TypeScript marks it on purpose: This comparison appears to be unintentional because the types 'typeof cartKey' and 'typeof savedKey' have no overlap. In plain words: "these two can never be equal, so you probably meant something else". It runs and prints false.

Typing constants

Most examples so far wrote their types. You don't have to: TypeScript works out a type from the starting value. With a const, the answer can surprise you:

A const and a let, with no types writtenPop out in the code editor (opens in a new tab)TypeScript
const minOrder = 50;//    ^?let cartTotal = 42;//  ^?cartTotal = 58;console.log(cartTotal >= minOrder);

Line 1 makes minOrder, the cart total that earns free shipping. The query on line 2 says const minOrder: 50. The type is 50, not number. A const can never change, so TypeScript keeps the exact value. 50 is still a number, so it works anywhere a number goes: line 6 compares it and prints true.

Line 3 makes cartTotal with let, and the query on line 4 says number. A let can change, so TypeScript allows any number later, like the 58 on line 5. Types that are one exact value, like 50, have a lesson of their own, Literal types. For now, read const minOrder: 50 as "a number that is always 50".

Left: a box minOrder made with const holds the card 50, and its type is 50. Right: a box cartTotal made with let holds the card 42, and its type is number, because any number may go in later.const minOrder = 5050minOrdertype: 50let cartTotal = 4242cartTotaltype: number
minOrder is a const, so it will always hold 50, and its type is 50. cartTotal is a let, so any number may go in later, and its type is number.

Each name still only takes what its declaration allows:

Changing a const, and text in a number (an error on purpose)Pop out in the code editor (opens in a new tab)TypeScript
const minOrder = 50;let cartTotal = 42; minOrder = 60;cartTotal = "free";

Both errors are on purpose:

  • Line 4: Cannot assign to 'minOrder' because it is a constant. "Assign" means "store a new value". A const can't take one, and JavaScript would throw a TypeError here (Variables covers const).
  • Line 5: Type 'string' is not assignable to type 'number'. cartTotal started as a number, so its type is number, and the text "free" can't go in.

You can still write a type on a constant. Then TypeScript uses the type you wrote instead of the exact value. Switch line 1 between the three ways to declare minOrder and watch the query on line 2:

Playground: const, let, or an annotation
A minimum order for free shippingPop out in the code editor (opens in a new tab)TypeScript
const minOrder = 50;//    ^?minOrder = 60;console.log(minOrder);
The type of minOrder50
What happens
TypeScript1 error: line 3
When it runsstops with a TypeError
Try it yourself

A const can never change, so TypeScript gives minOrder the exact type 50. Line 3 tries to change it anyway: Cannot assign to 'minOrder' because it is a constant. When it runs, JavaScript stops with a TypeError.

TypeScript checks the code for real, and the query on line 2 shows its answer. Each button changes only line 1. Reset goes back to const.

const gives 50 and an error on line 3. let gives number and no error. const with : number gives number but keeps the error, because the annotation changes the type, not the fact that it's a constant. Most constants don't need an annotation: const minOrder = 50 already says everything. Write one when you want the wider type, or to make sure the starting value is the kind you meant.

A product card on a shop page

A product card shows a name, a price, a stock badge, and a view count. Here are its values, each with the primitive type it needs, and the text the card shows:

The values behind a product cardPop out in the code editor (opens in a new tab)TypeScript
const title: string = "Green tea";const price: number = 3.5;const inStock: boolean = true;const views: bigint = 9007199254740993n; const label = `${title}: $${price.toFixed(2)}`;//    ^?const badge = inStock ? "In stock" : "Sold out";console.log(label, badge);console.log(`${views} views`);

Lines 1 to 4 hold the product's values: a string, a number, a boolean, and a bigint, because the view count is past what a number holds exactly. Line 6 builds the label with a template literal, and the query on line 7 shows it's a string. TypeScript allowed price.toFixed(2) because price is a number. Line 8 picks a badge from the boolean. Line 9 prints Green tea: $3.50 In stock, and line 10 prints 9007199254740993 views: inside a template literal, a bigint shows without its n.

Error or fine?
  • const title: string = "Green tea";
  • const price: number = "3.5";
  • const inStock: boolean = "yes";
  • const views: bigint = 10;
  • const views: bigint = 10n;
  • const coupon: string = null;
  • const discount: number = NaN;
  • const city: String = "Pune";
Try it yourself
0 of 8 correct

Sort each line by what TypeScript says about it. Each line is checked on its own.

Choose a category for every card. You can change an answer at any time; Reset clears them all.

Common mix-ups

  • "String and string are the same type." No. string is text. String is a wrapper object made with new String(…). Write lowercase.
  • "Decimals need a different type from whole numbers." No. 3 and 3.5 are both number. Only very large whole numbers need bigint.
  • "NaN isn't a number, so TypeScript rejects it." No. NaN is a value of the number type, and typeof NaN is "number".
  • "typeof null is "object", so null's type is an object." No. That's an old JavaScript mistake. TypeScript's type for null is null.
  • "null fits in any type." Only with strictNullChecks off. With it on, a string can't hold null or undefined.
  • "const minOrder = 50 has the type number." No. Its type is 50, because a const never changes. It still works anywhere a number goes.
  • "A bigint and a number can be added like any two numbers." No. TypeScript reports it, and JavaScript throws a TypeError. Convert one with BigInt(…) or Number(…) first.

Practice exercises

Each exercise is TypeScript. When you fix code, press Edit & run on the starter code: the errors update as you type, and the console shows what it prints. Try a guess first, then use the hints.

Exercise 1 · Warm-upRead a worked-out type

No types are written here. What type does TypeScript give inStock? Guess first, then point at inStock or add a // ^? line under it.

Starter codePop out in the code editor (opens in a new tab)TypeScript
let inStock = false;inStock = true;

Answer, then press Check. Spacing and letter case don’t matter.

    Exercise 2 · Warm-upFind the line TypeScript marks

    A sign-up form's values, one with a mistake. Which line will TypeScript mark?

    Starter codePop out in the code editor (opens in a new tab)TypeScript
    const userName: string = "Asha";
    const age: number = 31;
    const isMember: boolean = "true";
    const city: string = "Pune";

    Answer, then press Check. Spacing and letter case don’t matter.

      Exercise 3 · PracticeFix the capital-letter types

      TypeScript marks line 4. Fix the types so it's happy. What does the fixed code print?

      Starter codePop out in the code editor (opens in a new tab)TypeScript
      function greet(name: String): String {  return "Hi, " + name;}const message: string = greet("Asha");console.log(message);

      Answer, then press Check. Spacing and letter case don’t matter.

        Exercise 4 · PracticeAdd new views to a bigint

        Line 3 gets an error and would throw. Fix it without changing lines 1 and 2. What does it print?

        Starter codePop out in the code editor (opens in a new tab)TypeScript
        const totalViews: bigint = 9007199254740993n;const newViews: number = 2;console.log(totalViews + newViews);

        Answer, then press Check. Spacing and letter case don’t matter.

          Exercise 5 · ChallengePredict a constant's type

          What type does TypeScript give maxItems? And itemsInCart? Guess, then add ^? queries to check.

          Starter codePop out in the code editor (opens in a new tab)TypeScript
          const maxItems = 10;let itemsInCart = 3;itemsInCart = itemsInCart + 1;

          Answer, then press Check. Spacing and letter case don’t matter.

            Exercise 6 · ChallengeCompare the same symbol

            What does line 3 print? Then change line 2 so savedKey holds the cart's own symbol and the comparison is true.

            Starter codePop out in the code editor (opens in a new tab)TypeScript
            const cartKey = Symbol("cart");const savedKey = Symbol("cart");console.log(cartKey === savedKey);

            Answer, then press Check. Spacing and letter case don’t matter.

              Check your understanding

              For each question, keep two things apart: the type TypeScript gives a value, and what JavaScript does with it when the code runs. The quiz shows its code without the checker, so the error list doesn't give the answers away.

              The primitive types quiz · 7 questionsScore: first tries count
              1. Question 1 of 7Which annotation should a user's name, like "Asha", get?

                Choose an answer to see the explanation.

              2. Question 2 of 7Does TypeScript accept NaN as a discount, and what prints?

                Read the code, then predictPop out in the code editor (opens in a new tab)TypeScript
                const discount: number = NaN;
                console.log(typeof discount);

                Choose an answer to see the explanation.

              3. Question 3 of 7Which line does TypeScript flag in this coupon code?

                Read the code, then predictPop out in the code editor (opens in a new tab)TypeScript
                let coupon: string = "SAVE10";
                coupon = null;
                console.log(coupon);

                Choose an answer to see the explanation.

              4. Question 4 of 7What type does TypeScript show when you hover limit on line 1?

                Read the code, then predictPop out in the code editor (opens in a new tab)TypeScript
                const limit = 5;
                let count = 0;

                Choose an answer to see the explanation.

              5. Question 5 of 7What happens when this code adds 1 to a bigint?

                Read the code, then predictPop out in the code editor (opens in a new tab)TypeScript
                const views: bigint = 10n;
                console.log(views + 1);

                Choose an answer to see the explanation.

              6. Question 6 of 7What does typeof print for a coupon that is null?

                Read the code, then predictPop out in the code editor (opens in a new tab)TypeScript
                const coupon = null;
                console.log(typeof coupon);

                Choose an answer to see the explanation.

              7. Question 7 of 7How many primitive types does TypeScript have?

                Choose an answer to see the explanation.

              Key takeaways

              • TypeScript has seven primitive types: string, number, boolean, bigint, symbol, null, and undefined.
              • One number type covers whole numbers, decimals, and NaN. A bigint is a whole number of any size, written with n, and doesn't mix with numbers.
              • With strictNullChecks on, null and undefined are types of their own and don't fit in a string or number.
              • Write lowercase types. String, Number, and Boolean are wrapper objects.
              • A const gets its exact value as its type, like 50; a let gets number. An annotation replaces that with the type you wrote.

              Remember the one-liner.
              Seven lowercase types, one for each kind of simple value JavaScript has.

              Coming next: Type annotations & inference. It shows when to write a type yourself and when to let TypeScript work it out.

              CompleteFrontend Clear concepts. Working examples.