TYPESCRIPT

TypeScript Types: Syntax, Usage, and Examples

TypeScript types let you describe what kind of values your variables, function inputs, and outputs can hold. They help you catch mistakes early, before your code even runs.


How to Use types

A type is a label you attach to a value. You can add types to variables, function parameters, return values, and objects.

Basic syntax

letusername:string ="Nina";
letage:number =28;
letisMember:boolean =true;

The format is always:

name:type

So age: number means “age must be a number.”

Adding types to function parameters and returns

functiongreet(name:string):string {
return`Hi, ${name}!`;
}

const message =greet("Leo");

Here’s what’s happening:

  • name: string forces the input to be text
  • : string after the parentheses means the function must return a string

Typing arrays

constscores:number[] = [10,15,22];
consttags:string[] = ["sale","new","popular"];

number[] means “an array of numbers.”

Typing objects

constuser: {id:number;name:string;isActive:boolean } = {
id:101,
name:"Aisha",
isActive:false,
};

This object must contain the exact fields listed, with the correct value type for each one.


When to Use types

Types are useful anytime you want your code to be easier to work with, safer to refactor, and less error-prone.

1) Preventing common bugs

Small mistakes like mixing numbers and strings happen all the time.

lettotal:number =40;

// total = "40"; // ❌ Type error

TypeScript blocks the assignment immediately, so you don’t find out later in production.

2) Making function behavior clearer

Function types act like a contract. You can glance at them and know what the function expects.

functionaddTax(price:number,taxRate:number):number {
return price + price * taxRate;
}

No guessing needed.

3) Working with objects and APIs

API responses can be messy. Types give you a clear shape to rely on.

typeProduct = {
id:string;
name:string;
price:number;
};

functionprintProduct(product:Product) {
console.log(`${product.name}: €${product.price}`);
}

Now the app won’t accidentally try to print a missing price.

4) Refactoring without fear

Types make it safer to rename properties, change function inputs, or move code around. Your editor will point out what broke instantly.


Examples of types

Let’s look at realistic situations where TypeScript types make a big difference.

Example 1: Type inference in action

TypeScript often figures out types for you automatically. This is called type inference.

let city ="Boston";
// city = 42; // ❌ Error, city is inferred as string

You didn’t write : string, but TypeScript inferred it from "Boston".

Example 2: Union types for flexible values

Sometimes a value can be one of a few types. That’s where union types shine.

letuserId:number |string;

userId =42;
userId ="42";

This is useful for IDs because some systems store them as numbers, others as strings.

Example 3: Optional properties

Some object fields are not always present. Add ? to mark them as optional.

typeProfile = {
name:string;
bio?:string;
};

constprofile1:Profile = {name:"Kai" };
constprofile2:Profile = {name:"Kai",bio:"Frontend dev and coffee addict." };

bio?: string means “bio can be missing, but if it exists, it must be a string.”

Example 4: Using literal types for strict options

Literal types lock a value to a specific set of choices.

typeTheme ="light" |"dark";

lettheme:Theme ="dark";
// theme = "blue"; // ❌ Error

This helps prevent typos like "drak" from sneaking into your app.

Example 5: Tuples for fixed-length arrays

A tuple is an array with a fixed structure, including position-based types.

constlocation: [number,number] = [48.2082,16.3738];

This guarantees:

  • index 0 is a number (latitude)
  • index 1 is a number (longitude)

Learn More About types

Types go far beyond string and number. Here are some of the most common concepts you’ll run into as you level up.

Common built-in types

These are the ones you’ll use constantly:

  • string for text
  • number for integers and decimals
  • boolean for true or false
  • null for “intentionally empty”
  • undefined for “not assigned yet”
  • any for “skip type checking” (use sparingly)

Example:

letvalue:any =5;
value ="now a string";
value = {random:true };

Using any turns TypeScript into “JavaScript with extra steps,” so save it for rare cases.

The unknown type

unknown is safer than any. It forces you to check the value before using it.

letinput:unknown ="hello";

if (typeof input ==="string") {
console.log(input.toUpperCase());
}

This is great for handling user input or API data.

Creating custom types with type aliases

A type alias lets you name a type so you can reuse it.

typeEmail =string;
typePrice =number;

letcustomerEmail:Email ="customer@example.com";
letitemPrice:Price =19.99;

This doesn’t change runtime behavior, but it makes your code easier to understand.

Interfaces vs type aliases

Both are used to describe object shapes. In many everyday cases, they feel similar.

Using an interface:

interfaceUser {
id:number;
name:string;
}

Using a type alias:

typeUser = {
id:number;
name:string;
};

A practical guideline:

  • Use interface when modeling object shapes that might grow over time
  • Use type when you need unions, literal types, or more advanced combinations

Generics for reusable types

Generics let you write code that works with many types while staying safe.

function wrapValue<T>(value: T): T[] {
return [value];
}

const wrappedNumber =wrapValue(5);
const wrappedText =wrapValue("hi");

T stands for “some type,” and TypeScript fills it in automatically.

Type narrowing

Sometimes TypeScript knows a value could be multiple types, like string | number. Type narrowing is how you guide it.

functionprintLength(value:string |number) {
if (typeof value ==="string") {
console.log(value.length);
  }else {
console.log(value.toFixed(2));
  }
}

The typeof check narrows the type inside each branch.

Enums for named constants

Enums group related values under a readable name.

enumRole {
Admin,
Editor,
Viewer,
}

constcurrentRole:Role =Role.Editor;

Enums can be handy for roles, statuses, or modes, but literal unions are often lighter and more flexible in modern TypeScript.

Avoiding common type mistakes

1) Using any too quickly

any removes safety, so bugs can slip in silently.

2) Forgetting null checks

If a value can be null, TypeScript wants you to handle that.

letname:string |null =null;

if (name) {
console.log(name.toUpperCase());
}

3) Overcomplicating types early

Start simple. Add complexity only when the project actually needs it.


Summary

Types in TypeScript describe what values your code is allowed to use, which helps you avoid mistakes and makes code easier to maintain. You can apply them to variables, arrays, objects, and functions, and you can build more advanced structures using unions, generics, and type narrowing.

Once you get used to them, types feel less like extra work and more like a safety net that keeps your code from falling apart.