Start learning free

LESSON 15 OF 348 · VARIABLES

Type Annotations in TypeScript: Variables and Functions

Lesson Read the full explanation

In JavaScript, a variable happily holds a number one moment and a string the next — and you only find out something went wrong when the program is already running. TypeScript fixes this with type annotations: a small label after the variable's name that tells the compiler what kind of value lives there, forever.

The annotation goes after a colon, between the name and the =:

let score: number = 90;        // score holds numbers, always
const player: string = "Alice"; // player holds a string, and const means it never changes

From this line on, score is a number. You can do number things with it (score = score + 8;) and the compiler is happy. It works with both let and const.


Typed functions:

Annotations shine on functions. You label each parameter AND the value the function returns — the return type goes after the parameter list:

function add(a: number, b: number): number {
    return a + b;
}

Now nobody can call add("2", 3) by accident, and everyone knows add gives back a number. Try it and the compiler answers with error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.


The trap:

An annotation is a promise, and the compiler holds you to it. This looks innocent:

let count: number = 5;
count = "42";   // "42" is a string, not a number!

...but it never even runs. The compiler stops you immediately:

p1.ts(2,1): error TS2322: Type 'string' is not assignable to type 'number'.

Read that message carefully — you WILL see it again. It names the type you gave ('string') and the type you promised ('number'). That's not the compiler being mean: it just caught, before the program ever ran, a bug JavaScript would have let slip through.


Assignment
Follow the Coding Tutorial and put annotations to work:

  • declare let score: number = 90; and add 8 to it,
  • declare const player: string = "Alice";,
  • define function add(a: number, b: number): number returning a + b,
  • print player + " scored " + score, then print "add(2, 3) = " + add(2, 3).

The exact expected output is:

Alice scored 98
add(2, 3) = 5

Hint
The annotation always follows the name: name: type. For functions, the return type comes after the closing parenthesis: (a: number, b: number): number.


STEP 1 OF 7
    Ctrl + Enter to check

    TYPESCRIPT · VARIABLES

    Type Annotations in TypeScript, explained

    What an annotation is

    A type annotation is a label that tells the compiler what kind of value a variable, parameter or function result will hold. It goes after a colon:

    let score: number = 90;
    const player: string = "Alice";
    

    From these lines on, score can hold numbers only and player can hold a string only. Annotations work with both let and const, and the pattern is always the same: name: type.

    The label is a promise, and the compiler holds you to it. Break the promise and the compiler reports the problem at compile time:

    let count: number = 5;
    count = "42";
    
    error TS2322: Type 'string' is not assignable to type 'number'.
    

    This message is worth learning to read. It names the type you supplied ('string') and the type that was promised ('number'), and the line and column tell you where.

    Annotations on functions

    For a function, you label each parameter, and then the value it returns. The return type goes after the closing parenthesis of the parameter list:

    function add(a: number, b: number): number {
        return a + b;
    }
    

    This signature says that add takes two numbers and returns a number. The compiler checks both directions. A call with the wrong argument types is rejected:

    console.log(add("2", 3));
    

    The error is Argument of type 'string' is not assignable to parameter of type 'number'. A call with the wrong number of arguments is rejected too, with Expected 2 arguments, but got 1. In the other direction, a body that returns nothing, despite the number annotation, is reported as A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value. A function that returns nothing is annotated : void.

    Annotations disappear at run time

    TypeScript checks annotations when it compiles and then removes them. The compiled JavaScript for the function above is just function add(a, b) { return a + b; }. Annotations convert nothing and check nothing while the program runs. Their entire value is in the checks before that. For example, a number that arrives from outside the program as a string is not fixed by labelling it a number.

    Annotations are often optional

    When a variable gets a value at its declaration, TypeScript infers the type, so let score = 90; already makes score a number. Writing the annotation anyway makes the intent explicit. It is most valuable where the compiler cannot infer: function parameters. The lesson writes the annotations out so you can see the syntax.

    The lesson's exercise

    The program builds up in seven small steps. The expected output is two lines.

    1. Declare score as a let variable with the number annotation, starting at 90.
    2. Add 8 by reassigning: score = score + 8;. Because the type is number, the arithmetic is guaranteed safe.
    3. Declare player as a const with the string annotation and the value "Alice". As a const, it can never be reassigned at all.
    4. Define the signature of add: two number parameters, a and b, and a number return type.
    5. Fill in the body with return a + b;.
    6. Print the first line by joining player, the text " scored " and score with +. The number is converted to text when it is joined to a string.
    7. Print the second line by joining the label "add(2, 3) = " to the call add(2, 3). The call runs first, and its result is joined as text.
    let score: number = 90;
    score = score + 8;
    const player: string = "Alice";
    function add(a: number, b: number): number {
        return a + b;
    }
    console.log(player + " scored " + score);
    console.log("add(2, 3) = " + add(2, 3));
    

    Running it prints:

    Alice scored 98
    add(2, 3) = 5
    

    Common mistakes

    • Putting the annotation in the wrong place. It follows the name, not the type before it: score: number, not number score.
    • Forgetting the return annotation's position. It comes after the closing parenthesis, before the opening brace.
    • Assigning to a const. player = "Bob" fails with Cannot assign to 'player' because it is a constant, whatever the type.
    • Passing numbers as strings. "98" in quotes is a string, not a number.

    Key takeaways

    • An annotation is written name: type and works with let and const.
    • Functions annotate each parameter and their return value.
    • The compiler reports violations as errors, such as TS2322 and TS2345, at compile time.
    • Annotations vanish when the code is compiled, so they check nothing at run time.
    Keep going with TypeScriptAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free