TypeScript Type Aliases and Interfaces
TypeScript lets you define a type separately from the variables that use it.
Type aliases and interfaces make it easy to share one type between many variables and objects.
Type Aliases
A type alias gives a type a custom name.
You can create an alias for a primitive like string, or for more complex types such as objects and arrays.
Example
CarYear, CarType and CarModel are aliases for primitives. Car is an alias for an object type built from them.
CarYear (number), CarType (string) and CarModel (string), then a Car object alias with year, type and model using those aliases; declare typed constants for 2001, "Toyota" and "Corolla" and build a Car object from them. The example only declares values and prints nothing.
Output: TypeScript file and captured output
type CarYear = number
type CarType = string
type CarModel = string
type Car = {
year: CarYear,
type: CarType,
model: CarModel
}
const carYear: CarYear = 2001
const carType: CarType = "Toyota"
const carModel: CarModel = "Corolla"
const car: Car = {
year: carYear,
type: carType,
model: carModel
};
Intersection and union aliases
A type alias can also combine types with & (intersection) or list allowed values with | (union).
type Animal = { name: string };
type Bear = Animal & { honey: boolean };
const bear: Bear = { name: "Winnie", honey: true };
type Status = "success" | "error";
let response: Status = "success";
Interfaces
Interfaces are similar to type aliases, but they only describe object types.
Example
The Rectangle interface says an object must have a numeric height and width.
Rectangle with numeric height and width, then create a rectangle constant of that type with height 20 and width 10. The example only declares values and prints nothing.
Output: TypeScript file and captured output
interface Rectangle {
height: number,
width: number
}
const rectangle: Rectangle = {
height: 20,
width: 10
};
Declaration merging
Declaring the same interface name twice merges the two declarations into one interface with all the properties.
interface Animal { name: string; }
interface Animal { age: number; }
const dog: Animal = { name: "Fido", age: 5 };
Type vs Interface: Key Differences
- Extending: Both can be extended, but only interfaces support declaration merging.
- Unions/Intersections: Only type aliases can describe union and intersection types.
- Implements: A class can implement either one.
- Recommendation: Use
interfacefor objects andtypefor everything else.
Best Practices:
- Use
interfaceto define object shapes and public APIs. - Use
typefor unions, intersections and primitives. - Prefer composing small types over deep inheritance.
- Document your types and interfaces so their purpose is clear.
Common Pitfalls:
- Using
typewhen you need declaration merging (useinterfaceinstead). - Overcomplicating types — keep them simple and focused.
- Forgetting to update types and interfaces as the code changes.
Extending Interfaces
An interface can extend another interface.
Note: Extending an interface means you create a new interface with all the properties of the original, plus something new.
Example
ColoredRectangle has everything Rectangle has, plus a color property.
Rectangle interface with numeric height and width, then a ColoredRectangle interface that extends it with a string color; create a coloredRectangle constant with height 20, width 10 and color "red". The example only declares values and prints nothing.
Output: TypeScript file and captured output
interface Rectangle {
height: number,
width: number
}
interface ColoredRectangle extends Rectangle {
color: string
}
const coloredRectangle: ColoredRectangle = {
height: 20,
width: 10,
color: "red"
};