Skip to content

Your First TypeScript File

The previous lesson showed the compiler in isolation. This lesson puts type annotations into real code — variables, functions, and objects — so you can see exactly how TypeScript uses them.

A type annotation follows the variable name with a colon:

const name: string = 'AceIt';
const questionCount: number = 10;
const isRunning: boolean = false;

TypeScript now knows the type of each variable. If you try to assign the wrong type later, the compiler reports an error before the code runs.

Function parameter and return type annotations

Section titled “Function parameter and return type annotations”

This is where annotations pay off most immediately. Without types, a function’s contract is invisible:

// JavaScript — what does this expect? What does it return?
function buildUrl(amount, difficulty) {
return `https://opentdb.com/api.php?amount=${amount}&difficulty=${difficulty}`;
}

With TypeScript, the contract is explicit:

function buildUrl(amount: number, difficulty: string): string {
return `https://opentdb.com/api.php?amount=${amount}&difficulty=${difficulty}`;
}

Now the compiler enforces that amount is always a number and difficulty is always a string. Callers that pass the wrong type get an error at write time:

buildUrl('10', 'easy'); // Error: Argument of type 'string' is not assignable to parameter of type 'number'
buildUrl(10, 'easy'); // ✓

You can describe the shape of an object inline:

const question: { text: string; answer: string } = {
text: 'What is the capital of France?',
answer: 'Paris',
};

This tells TypeScript that question must have a text property and an answer property, both strings. Accessing a property that does not exist is an error:

console.log(question.category); // Error: Property 'category' does not exist

Inline object shapes become unwieldy for larger structures — Module 03 covers interfaces, which give these shapes names. For now, inline annotations are enough.

Functions that return nothing are annotated with void:

function logScore(score: number, total: number): void {
console.log(`Score: ${score} / ${total}`);
}

Attempting to return a value from a void function is a compiler error. This prevents accidental returns in functions that are only supposed to produce side effects.

A key mental shift with TypeScript: type errors stop the compile, they do not throw at runtime. The browser never sees the broken code. This is fundamentally different from a JavaScript runtime error, which only surfaces when the bad line actually executes.

Write this in main.ts:

function greet(name: string): string {
return 'Hello, ' + name;
}
greet(42); // Type error — caught by tsc, never reaches the browser

Run npx tsc. The compiler reports the error and produces no output. Fix 42 to 'World' and recompile — the error resolves and main.js is written.

Create quiz.ts in your aceit/ folder. Write the following functions with full type annotations:

  1. buildUrl(amount: number, difficulty: string): string — returns the Open Trivia DB URL with the given parameters appended as query string values.
  2. formatScore(score: number, total: number): string — returns a string like "7 / 10 correct".
  3. isHighScore(score: number, total: number, previousBest: number): boolean — returns true if score / total is greater than previousBest.

Compile with npx tsc quiz.ts and fix any errors before moving on.

  • Type annotations follow the variable or parameter name with a colon: name: string.
  • Function parameters and return types are annotated separately: (amount: number): string.
  • Object shapes can be described inline: { text: string; answer: string }.
  • void is the return type for functions that return nothing.
  • Type errors prevent compilation — the browser never runs code with type errors.