Why Types? From JavaScript to TypeScript
What a type system buys you, and how TypeScript catches a bug that JavaScript happily runs.
What you'll learn
- Explain what a static type system checks, and when it checks it
- Annotate a variable with an explicit type
- Predict whether a given assignment will be rejected by the compiler
Explanation
JavaScript checks almost nothing before your code runs. This function looks fine:
function applyDiscount(price, percent) {
return price - price * (percent / 100);
}
Call it as applyDiscount("20", 10) and JavaScript does not complain. It converts, guesses, and hands back NaN — "not a number" — which then flows into a total, then into a receipt, and surfaces days later as a support ticket. The mistake happened at the call site; the symptom appeared somewhere else entirely. That distance is what makes these bugs expensive.
TypeScript is JavaScript plus a static type system. "Static" means the checking happens before the program runs — while you type, and again when you build. You describe what a value is allowed to be, and the compiler holds every line to that description.
function applyDiscount(price: number, percent: number): number {
return price - price * (percent / 100);
}
Now applyDiscount("20", 10) is rejected with a specific complaint: Argument of type 'string' is not assignable to parameter of type 'number'. The error names the wrong value, the expected type, and the exact position. You fix it in seconds instead of hours.
The annotation syntax is a colon after the name: const total: number = 0. You will meet it on variables, parameters, and return types.
Two things worth understanding early, because they explain most of TypeScript's behaviour:
TypeScript erases at runtime. Types are checking instructions for the compiler, not values your program can inspect. The emitted JavaScript has every annotation stripped out. There is no type information left to consult while the program runs, which is why you cannot ask "what type is this variable?" the way you can ask typeof about a value.
A type error does not necessarily stop the build. By default TypeScript still emits JavaScript when it finds type errors, on the theory that you may want to run the parts that are fine while you fix the rest. In this lab you will see both: the error and the output. That is not the lab being lenient — it is the compiler's actual default.
Types are not paperwork you add at the end. They are a description of intent that the compiler enforces for you, forever, on every future edit.
Example
The same calculation with annotations. Note the third call: the compiler objects before this ever runs.
function applyDiscount(price: number, percent: number): number {
return price - price * (percent / 100);
}
console.log(applyDiscount(200, 10));
console.log(applyDiscount(59.99, 25));
// Uncomment the next line to see the compiler reject it:
// console.log(applyDiscount("200", 10));Try it yourself
Try it: uncomment the last line and press Run. Read the error, then fix it by passing a number.
Code editor. Press Escape then Tab to leave the editor if keyboard focus becomes trapped. Press Control+Shift+M inside the editor to toggle Tab-key focus trapping.
Guided exercise
Guided exercise
Declare a variable `courseTitle` explicitly typed as `string`, and a variable `lessonCount` explicitly typed as `number`. Give each a sensible value, then log both.
Checks: courseTitle is a non-empty string · lessonCount is a number
Code editor. Press Escape then Tab to leave the editor if keyboard focus becomes trapped. Press Control+Shift+M inside the editor to toggle Tab-key focus trapping.
Stuck? Get a hint.
Independent exercise
Independent exercise
Write a function `secondsToMinutes(seconds: number): number` that converts seconds to whole minutes, rounded down. Annotate both the parameter and the return type. `secondsToMinutes(150)` should return 2.
Checks: secondsToMinutes is defined · secondsToMinutes(150) returns 2 · plus 1 hidden check
Code editor. Press Escape then Tab to leave the editor if keyboard focus becomes trapped. Press Control+Shift+M inside the editor to toggle Tab-key focus trapping.
Stuck? Get a hint.
Common mistakes
- Believing types still exist at runtime. They are erased during compilation — you cannot check a variable's declared type while the program runs.
- Annotating everything, including values TypeScript could already infer. The next lesson covers when an annotation adds nothing.
- Assuming a type error blocks execution. Without `noEmitOnError`, TypeScript still emits JavaScript and the code still runs.
Knowledge check
Takeaway
TypeScript checks your intent before the code runs, then erases itself — you get the errors without paying anything at runtime.
Summary
TypeScript adds a static type system to JavaScript. You annotate values with `name: type`, the compiler rejects assignments that contradict those annotations, and the types disappear from the emitted JavaScript.
References
Your notes
Notes save automatically.
Finished this lesson?
Mark it complete to track your progress and schedule a future review.
AI tutor
The optional AI tutor isn't enabled in this deployment. All lessons, exercises, quizzes, and search work fully without it.