How to Define a Type in TypeScript

What you’ll build or solve

You’ll define types using type and interface, then apply them to objects and functions. By the end, you’ll know how to create reusable types for real data structures and function contracts.

When this approach works best

This method works best when:

  • You want to describe the structure of objects passed around your app.
  • You reuse the same data shape across multiple files or functions.
  • You want safer function parameters for API responses or UI state.

Skip this when a built-in type like string or number is enough for a one-off variable.

Prerequisites

  • TypeScript installed
  • Basic understanding of JavaScript objects and functions

No extra tools are required beyond TypeScript.


Step-by-step instructions

Step 1: Define a type alias

Use type to create a named type you can reuse.

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

Use it like this:

constuser:User= {
  id:1,
  name:"Sam",
  email:"sam@example.com",
};

You can also mark properties as optional inside the type:

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

What to look for

  • Type errors if a required property is missing.
  • Clear messages when you assign the wrong value type.

Step 2: Define an interface

Use interface to describe an object shape, especially in codebases that prefer interface-based modeling.

interfaceProduct {
  id:number;
  title:string;
  price:number;
}

Use it:

constproduct:Product= {
  id:10,
  title:"Laptop",
  price:999,
};

You can mark properties as readonly inside an interface:

interfaceConfig {
readonly apiKey:string;
}

What to look for

  • Errors if you try to reassign a readonly property.
  • Interfaces are commonly used for object shapes and can be extended in many projects.

Step 3: Define a union type

Union types restrict values to a set of allowed types or literals.

typeStatus="pending"|"approved"|"rejected";

Use it:

letorderStatus:Status="pending";

This fails:

orderStatus="shipped";

What to look for

  • TypeScript blocks values that are not in the allowed set.
  • Union types work well for state, variants, and mode flags.

Step 4: Define a function type

Function types describe what a function accepts and returns.

typeAddFunction= (a:number,b:number) =>number;

Use it:

constadd:AddFunction= (a,b) =>a+b;

What to look for

  • Errors if parameters or return types don’t match the function type.

Step 5: Define types using intersections

Intersections combine multiple types into one.

typePerson= {
  name:string;
};

typeEmployee= {
  employeeId:number;
};

typeStaffMember=Person&Employee;

Use it:

conststaff:StaffMember= {
  name:"Jordan",
  employeeId:123,
};

What to look for

  • All properties from each type are required in the combined type.
  • Intersections are useful when you compose behavior or data from multiple sources.

Examples you can copy

Example 1: API response shape

typeApiResponse= {
  success:boolean;
  data:string[];
};

constresponse:ApiResponse= {
  success:true,
  data: ["Item 1","Item 2"],
};

Example 2: Function parameter contract

interfaceLoginData {
  email:string;
  password:string;
}

functionlogin(data:LoginData) {
console.log(data.email);
}

Example 3: Flexible identifier type

typeIdentifier=string|number;

functionprintId(id:Identifier) {
console.log(id);
}

Common mistakes and how to fix them

Mistake 1: Using any instead of defining a type

What someone might do:

letuser:any= { name:"Sam" };

Why it breaks:

any disables type checking, so mistakes slip through.

Correct approach:

typeUser= {
  name:string;
};

letuser:User= { name:"Sam" };

Mistake 2: Mixing up union and intersection

What someone might do:

typeA= { a:string };
typeB= { b:number };

typeC=A|B;

Why it breaks:

A | B means one or the other, so you can’t assume both properties exist.

Correct approach:

typeC=A&B;

Use & when you need all properties.


Mistake 3: Forgetting to mark a property optional

What someone might do:

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

constuser:User= { name:"Alex" };

Why it breaks:

age is required.

Correct approach:

typeUser= {
  name:string;
  age?:number;
};

Troubleshooting

If TypeScript says a property does not exist, check spelling and confirm the type includes it.

If union types cause errors, narrow the type before using type-specific methods.

If you see duplicate identifier errors, you may have defined the same type name in more than one place.

If types seem ignored, confirm the file is being compiled and rerun tsc.


Quick recap

  • Use type to define reusable named types and compose them with unions or intersections.
  • Use interface to define object shapes, often for models and public APIs.
  • Use unions to restrict values to allowed options.
  • Use function types to describe callable shapes.
  • Use intersections to combine multiple type shapes into one.