In TypeScript, both type
and interface
are used to define custom types. While they have similarities, there are key differences and best-use scenarios for each. Here's a detailed comparison:
type
Type Aliases: The type
keyword is used to create type aliases. These can represent primitive types, union types, intersection types, tuples, and more complex types.
type StringAlias = string;
type NumberOrString = number | string;
type TupleType = [number, string];
Flexibility: type
is more flexible than interface
in certain aspects. For example, type
can define union types, intersection types, and other complex types that interface
cannot.
type UnionType = { x: number } | { y: string };
type IntersectionType = { x: number } & { y: string };
Utility Types: TypeScript’s utility types work with type aliases. For instance, Partial
, Required
, Readonly
, etc., can be used with type
.
type Person = {
name: string;
age: number;
};
type ReadonlyPerson = Readonly<Person>;
Literal Types: type
can also define literal types.
type Direction = "left" | "right" | "up" | "down";
interface
Object Shapes: The interface
keyword is typically used to define the shape of objects. It's best suited for defining objects with named properties.
interface Person {
name: string;
age: number;
}
Extending: interface
can extend other interfaces and types, which allows for a more declarative approach to composition.
interface Named {
name: string;
}
interface Aged {
age: number;
}
interface Person extends Named, Aged {}
Implementation: Classes can implement interfaces, ensuring they adhere to a specific contract.
class Employee implements Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
Declaration Merging: One unique feature of interfaces is declaration merging, where multiple declarations with the same name are merged into a single interface. This can be useful for augmenting types.
interface Person {
name: string;
}
interface Person {
age: number;
}
// Person now has both `name` and `age`
Use type
for creating type aliases, union types, intersection types, tuples, and more complex types.
Use interface
for defining the shape of objects, especially when you need to take advantage of declaration merging or when implementing interfaces with classes.
In many cases, either type
or interface
can be used interchangeably, but understanding their differences helps in choosing the right tool for the job.