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.
- Declare
scoreas aletvariable with thenumberannotation, starting at 90. - Add 8 by reassigning:
score = score + 8;. Because the type isnumber, the arithmetic is guaranteed safe. - Declare
playeras aconstwith thestringannotation and the value"Alice". As aconst, it can never be reassigned at all. - Define the signature of
add: twonumberparameters,aandb, and anumberreturn type. - Fill in the body with
return a + b;. - Print the first line by joining
player, the text" scored "andscorewith+. The number is converted to text when it is joined to a string. - Print the second line by joining the label
"add(2, 3) = "to the calladd(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, notnumber score. - Forgetting the return annotation's position. It comes after the closing parenthesis, before the opening brace.
- Assigning to a
const.player = "Bob"fails withCannot 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: typeand works withletandconst. - Functions annotate each parameter and their return value.
- The compiler reports violations as errors, such as
TS2322andTS2345, at compile time. - Annotations vanish when the code is compiled, so they check nothing at run time.